public ActionResult Search(CatalogSearchQuery query)
        {
            var model = new SearchResultModel(query);
            CatalogSearchResult result = null;

            if (query.Term == null || query.Term.Length < _searchSettings.InstantSearchTermMinLength)
            {
                model.SearchResult = new CatalogSearchResult(query);
                model.Error        = T("Search.SearchTermMinimumLengthIsNCharacters", _searchSettings.InstantSearchTermMinLength);
                return(View(model));
            }

            // 'Continue shopping' URL
            _genericAttributeService.SaveAttribute(Services.WorkContext.CurrentCustomer,
                                                   SystemCustomerAttributeNames.LastContinueShoppingPage,
                                                   Services.WebHelper.GetThisPageUrl(false),
                                                   Services.StoreContext.CurrentStore.Id);

            try
            {
                result = _catalogSearchService.Search(query);
            }
            catch (Exception ex)
            {
                model.Error = ex.ToString();
                result      = new CatalogSearchResult(query);
            }

            if (result.TotalHitsCount == 0 && result.SpellCheckerSuggestions.Any())
            {
                // No matches, but spell checker made a suggestion.
                // We implicitly search again with the first suggested term.
                var oldSuggestions = result.SpellCheckerSuggestions;
                var oldTerm        = query.Term;
                query.Term = oldSuggestions[0];

                result = _catalogSearchService.Search(query);

                if (result.TotalHitsCount > 0)
                {
                    model.AttemptedTerm = oldTerm;
                    // Restore the original suggestions.
                    result.SpellCheckerSuggestions = oldSuggestions.Where(x => x != query.Term).ToArray();
                }
                else
                {
                    query.Term = oldTerm;
                }
            }

            model.SearchResult       = result;
            model.Term               = query.Term;
            model.TotalProductsCount = result.TotalHitsCount;

            var mappingSettings = _catalogHelper.GetBestFitProductSummaryMappingSettings(query.GetViewMode());
            var summaryModel    = _catalogHelper.MapProductSummaryModel(result.Hits, mappingSettings);

            // Prepare paging/sorting/mode stuff.
            _catalogHelper.MapListActions(summaryModel, null, _catalogSettings.DefaultPageSizeOptions);

            // Add product hits.
            model.TopProducts = summaryModel;

            return(View(model));
        }
示例#2
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));
        }
示例#3
0
        public ActionResult Manufacturer(int manufacturerId, CatalogSearchQuery query)
        {
            var manufacturer = _manufacturerService.GetManufacturerById(manufacturerId);

            if (manufacturer == null || manufacturer.Deleted)
            {
                return(HttpNotFound());
            }

            // Check whether the current user has a "Manage catalog" permission
            // It allows him to preview a manufacturer before publishing
            if (!manufacturer.Published && !_services.Permissions.Authorize(StandardPermissionProvider.ManageCatalog))
            {
                return(HttpNotFound());
            }

            //Store mapping
            if (!_storeMappingService.Authorize(manufacturer))
            {
                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 = manufacturer.ToModel();

            // prepare picture model
            model.PictureModel = _helper.PrepareManufacturerPictureModel(manufacturer, model.Name);

            var customerRolesIds = _services.WorkContext.CurrentCustomer.CustomerRoles.Where(x => x.Active).Select(x => x.Id).ToList();

            // Featured products
            if (!_catalogSettings.IgnoreFeaturedProducts)
            {
                CatalogSearchResult featuredProductsResult = null;

                string cacheKey = ModelCacheEventConsumer.MANUFACTURER_HAS_FEATURED_PRODUCTS_KEY.FormatInvariant(
                    manufacturerId, string.Join(",", customerRolesIds), _services.StoreContext.CurrentStore.Id);
                var hasFeaturedProductsCache = _services.Cache.Get <bool?>(cacheKey);

                var featuredProductsQuery = new CatalogSearchQuery()
                                            .VisibleOnly(_services.WorkContext.CurrentCustomer)
                                            .VisibleIndividuallyOnly(true)
                                            .WithManufacturerIds(true, manufacturerId)
                                            .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)
                {
                    // TODO: (mc) determine settings properly
                    var featuredProductsmappingSettings = _helper.GetBestFitProductSummaryMappingSettings(ProductSummaryViewMode.Grid);
                    model.FeaturedProducts = _helper.MapProductSummaryModel(featuredProductsResult.Hits, featuredProductsmappingSettings);
                }
            }

            // Products
            query.WithManufacturerIds(_catalogSettings.IncludeFeaturedProductsInNormalLists ? null : (bool?)false, manufacturerId);

            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, manufacturer, _catalogSettings.DefaultPageSizeOptions);

            // Template
            var templateCacheKey = string.Format(ModelCacheEventConsumer.MANUFACTURER_TEMPLATE_MODEL_KEY, manufacturer.ManufacturerTemplateId);
            var templateViewPath = _services.Cache.Get(templateCacheKey, () =>
            {
                var template = _manufacturerTemplateService.GetManufacturerTemplateById(manufacturer.ManufacturerTemplateId);
                if (template == null)
                {
                    template = _manufacturerTemplateService.GetAllManufacturerTemplates().FirstOrDefault();
                }
                return(template.ViewPath);
            });

            //activity log
            _services.CustomerActivity.InsertActivity("PublicStore.ViewManufacturer", T("ActivityLog.PublicStore.ViewManufacturer"), manufacturer.Name);

            _services.DisplayControl.Announce(manufacturer);

            return(View(templateViewPath, model));
        }
        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(Permissions.Catalog.Category.Read))
            {
                return(HttpNotFound());
            }

            // ACL (access control list).
            if (!_aclService.Authorize(category))
            {
                return(HttpNotFound());
            }

            // Store mapping.
            if (!_storeMappingService.Authorize(category))
            {
                return(HttpNotFound());
            }

            var store    = Services.StoreContext.CurrentStore;
            var customer = Services.WorkContext.CurrentCustomer;

            // 'Continue shopping' URL.
            if (!Services.WorkContext.CurrentCustomer.IsSystemAccount)
            {
                _genericAttributeService.SaveAttribute(customer, SystemCustomerAttributeNames.LastContinueShoppingPage, Services.WebHelper.GetThisPageUrl(false), store.Id);
            }

            var model = category.ToModel();

            if (query.IsSubPage && !_catalogSettings.ShowDescriptionInSubPages)
            {
                model.Description.ChangeValue(string.Empty);
                model.BottomDescription.ChangeValue(string.Empty);
            }

            model.PictureModel = _helper.PrepareCategoryPictureModel(category, model.Name);

            // Category breadcrumb.
            if (_catalogSettings.CategoryBreadcrumbEnabled)
            {
                _helper.GetBreadcrumb(_breadcrumb, ControllerContext);
            }

            // Products.
            var 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);

            model.SubCategoryDisplayType = _catalogSettings.SubCategoryDisplayType;

            var customerRolesIds = customer.CustomerRoleMappings
                                   .Select(x => x.CustomerRole)
                                   .Where(x => x.Active)
                                   .Select(x => x.Id)
                                   .ToList();

            var pictureSize  = _mediaSettings.CategoryThumbPictureSize;
            var fallbackType = _catalogSettings.HideCategoryDefaultPictures ? FallbackPictureType.NoFallback : FallbackPictureType.Entity;

            var hideSubCategories = _catalogSettings.SubCategoryDisplayType == SubCategoryDisplayType.Hide ||
                                    (_catalogSettings.SubCategoryDisplayType == SubCategoryDisplayType.AboveProductList && query.IsSubPage && !_catalogSettings.ShowSubCategoriesInSubPages);
            var hideFeaturedProducts = _catalogSettings.IgnoreFeaturedProducts || (query.IsSubPage && !_catalogSettings.IncludeFeaturedProductsInSubPages);

            // Subcategories.
            if (!hideSubCategories)
            {
                var subCategories = _categoryService.GetAllCategoriesByParentCategoryId(categoryId);
                model.SubCategories = _helper.MapCategorySummaryModel(subCategories, pictureSize);
            }

            // Featured Products.
            if (!hideFeaturedProducts)
            {
                CatalogSearchResult featuredProductsResult = null;

                string cacheKey = ModelCacheEventConsumer.CATEGORY_HAS_FEATURED_PRODUCTS_KEY.FormatInvariant(categoryId, string.Join(",", customerRolesIds), store.Id);
                var    hasFeaturedProductsCache = Services.Cache.Get <bool?>(cacheKey);

                var featuredProductsQuery = new CatalogSearchQuery()
                                            .VisibleOnly(customer)
                                            .WithVisibility(ProductVisibility.Full)
                                            .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);
                }
            }

            // 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));
        }
示例#5
0
        public async Task <IActionResult> Search(CatalogSearchQuery query)
        {
            var model = new SearchResultModel(query);
            CatalogSearchResult result = null;

            if (query.Term == null || query.Term.Length < _searchSettings.InstantSearchTermMinLength)
            {
                model.SearchResult = new CatalogSearchResult(query);
                model.Error        = T("Search.SearchTermMinimumLengthIsNCharacters", _searchSettings.InstantSearchTermMinLength);
                return(View(model));
            }

            Services.WorkContext.CurrentCustomer.GenericAttributes.LastContinueShoppingPage = Services.WebHelper.GetCurrentPageUrl(false);

            try
            {
                if (_searchSettings.SearchProductByIdentificationNumber)
                {
                    var(product, attributeCombination) = await _productService.Value.GetProductByIdentificationNumberAsync(query.Term);

                    if (product != null)
                    {
                        if (attributeCombination != null)
                        {
                            return(Redirect(await _productUrlHelper.GetProductUrlAsync(product.Id, await product.GetActiveSlugAsync(), attributeCombination.AttributeSelection)));
                        }

                        return(RedirectToRoute("Product", new { SeName = await product.GetActiveSlugAsync() }));
                    }
                }

                result = await _catalogSearchService.SearchAsync(query);
            }
            catch (Exception ex)
            {
                model.Error = ex.ToString();
                result      = new CatalogSearchResult(query);
            }

            if (result.TotalHitsCount == 0 && result.SpellCheckerSuggestions.Any())
            {
                // No matches, but spell checker made a suggestion.
                // We implicitly search again with the first suggested term.
                var oldSuggestions = result.SpellCheckerSuggestions;
                var oldTerm        = query.Term;
                query.Term = oldSuggestions[0];

                result = await _catalogSearchService.SearchAsync(query);

                if (result.TotalHitsCount > 0)
                {
                    model.AttemptedTerm = oldTerm;
                    // Restore the original suggestions.
                    result.SpellCheckerSuggestions = oldSuggestions.Where(x => x != query.Term).ToArray();
                }
                else
                {
                    query.Term = oldTerm;
                }
            }

            model.SearchResult       = result;
            model.Term               = query.Term;
            model.TotalProductsCount = result.TotalHitsCount;

            var mappingSettings = _catalogHelper.GetBestFitProductSummaryMappingSettings(_catalogHelper.GetSearchQueryViewMode(query));
            var summaryModel    = await _catalogHelper.MapProductSummaryModelAsync(await result.GetHitsAsync(), mappingSettings);

            // Prepare paging/sorting/mode stuff.
            _catalogHelper.MapListActions(summaryModel, null, _catalogSettings.DefaultPageSizeOptions);

            // Add product hits.
            model.TopProducts = summaryModel;

            return(View(model));
        }
示例#6
0
        public async Task <IActionResult> Category(int categoryId, CatalogSearchQuery query)
        {
            var category = await _db.Categories
                           .Include(x => x.MediaFile)
                           .FindByIdAsync(categoryId, false);

            if (category == null || category.Deleted)
            {
                return(NotFound());
            }

            // Check whether the current user has a "Manage catalog" permission.
            // It allows him to preview a category before publishing.
            if (!category.Published && !await Services.Permissions.AuthorizeAsync(Permissions.Catalog.Category.Read))
            {
                return(NotFound());
            }

            // ACL (access control list).
            if (!await _aclService.AuthorizeAsync(category))
            {
                return(NotFound());
            }

            // Store mapping.
            if (!await _storeMappingService.AuthorizeAsync(category))
            {
                return(NotFound());
            }

            var customer = Services.WorkContext.CurrentCustomer;
            var storeId  = Services.StoreContext.CurrentStore.Id;

            // 'Continue shopping' URL.
            if (!customer.IsSystemAccount)
            {
                customer.GenericAttributes.LastContinueShoppingPage = Services.WebHelper.GetCurrentPageUrl(false);
            }

            var model = await _helper.PrepareCategoryModelAsync(category);

            if (_seoSettings.CanonicalUrlsEnabled)
            {
                model.CanonicalUrl = _urlHelper.Value.RouteUrl("Category", new { model.SeName }, Request.Scheme);
            }

            if (query.IsSubPage && !_catalogSettings.ShowDescriptionInSubPages)
            {
                model.Description.ChangeValue(string.Empty);
                model.BottomDescription.ChangeValue(string.Empty);
            }

            model.Image = await _helper.PrepareCategoryImageModelAsync(category, model.Name);

            // Category breadcrumb.
            if (_catalogSettings.CategoryBreadcrumbEnabled)
            {
                await _helper.GetBreadcrumbAsync(_breadcrumb, ControllerContext);
            }

            // Products.
            var catIds = new int[] { categoryId };

            if (_catalogSettings.ShowProductsFromSubcategories)
            {
                // Include subcategories.
                catIds = catIds.Concat(await _helper.GetChildCategoryIdsAsync(categoryId)).ToArray();
            }

            query.WithCategoryIds(_catalogSettings.IncludeFeaturedProductsInNormalLists ? null : false, catIds);

            var searchResult = await _catalogSearchService.SearchAsync(query);

            model.SearchResult = searchResult;

            var viewMode        = _helper.GetSearchQueryViewMode(query);
            var mappingSettings = _helper.GetBestFitProductSummaryMappingSettings(viewMode);

            model.Products = await _helper.MapProductSummaryModelAsync(await searchResult.GetHitsAsync(), mappingSettings);

            model.SubCategoryDisplayType = _catalogSettings.SubCategoryDisplayType;

            var pictureSize  = _mediaSettings.CategoryThumbPictureSize;
            var fallbackType = _catalogSettings.HideCategoryDefaultPictures ? FallbackPictureType.NoFallback : FallbackPictureType.Entity;

            var hideSubCategories = _catalogSettings.SubCategoryDisplayType == SubCategoryDisplayType.Hide ||
                                    (_catalogSettings.SubCategoryDisplayType == SubCategoryDisplayType.AboveProductList && query.IsSubPage && !_catalogSettings.ShowSubCategoriesInSubPages);
            var hideFeaturedProducts = _catalogSettings.IgnoreFeaturedProducts || (query.IsSubPage && !_catalogSettings.IncludeFeaturedProductsInSubPages);

            // Subcategories.
            if (!hideSubCategories)
            {
                var subCategories = await _categoryService.GetCategoriesByParentCategoryIdAsync(categoryId);

                model.SubCategories = await _helper.MapCategorySummaryModelAsync(subCategories, pictureSize);
            }

            // Featured Products.
            if (!hideFeaturedProducts)
            {
                CatalogSearchResult featuredProductsResult = null;

                string cacheKey = ModelCacheInvalidator.CATEGORY_HAS_FEATURED_PRODUCTS_KEY.FormatInvariant(categoryId, string.Join(",", customer.GetRoleIds()), storeId);
                var    hasFeaturedProductsCache = await Services.Cache.GetAsync <bool?>(cacheKey);

                var featuredProductsQuery = new CatalogSearchQuery()
                                            .VisibleOnly(customer)
                                            .WithVisibility(ProductVisibility.Full)
                                            .WithCategoryIds(true, categoryId)
                                            .HasStoreId(storeId)
                                            .WithLanguage(Services.WorkContext.WorkingLanguage)
                                            .WithCurrency(Services.WorkContext.WorkingCurrency);

                if (!hasFeaturedProductsCache.HasValue)
                {
                    featuredProductsResult = await _catalogSearchService.SearchAsync(featuredProductsQuery);

                    hasFeaturedProductsCache = featuredProductsResult.TotalHitsCount > 0;
                    await Services.Cache.PutAsync(cacheKey, hasFeaturedProductsCache);
                }

                if (hasFeaturedProductsCache.Value && featuredProductsResult == null)
                {
                    featuredProductsResult = await _catalogSearchService.SearchAsync(featuredProductsQuery);
                }

                if (featuredProductsResult != null)
                {
                    var featuredProductsMappingSettings = _helper.GetBestFitProductSummaryMappingSettings(ProductSummaryViewMode.Grid);
                    model.FeaturedProducts = await _helper.MapProductSummaryModelAsync(await featuredProductsResult.GetHitsAsync(), featuredProductsMappingSettings);
                }
            }

            // Prepare paging/sorting/mode stuff.
            _helper.MapListActions(model.Products, category, _catalogSettings.DefaultPageSizeOptions);

            // Template.
            var templateCacheKey = string.Format(ModelCacheInvalidator.CATEGORY_TEMPLATE_MODEL_KEY, category.CategoryTemplateId);
            var templateViewPath = await Services.Cache.GetAsync(templateCacheKey, async() =>
            {
                var template = await _db.CategoryTemplates.FindByIdAsync(category.CategoryTemplateId, false)
                               ?? await _db.CategoryTemplates.FirstOrDefaultAsync();

                return(template.ViewPath);
            });

            // Activity log.
            Services.ActivityLogger.LogActivity("PublicStore.ViewCategory", T("ActivityLog.PublicStore.ViewCategory"), category.Name);

            Services.DisplayControl.Announce(category);

            return(View(templateViewPath, model));
        }
示例#7
0
        public async Task <IActionResult> Manufacturer(int manufacturerId, CatalogSearchQuery query)
        {
            var manufacturer = await _db.Manufacturers.FindByIdAsync(manufacturerId, false);

            if (manufacturer == null || manufacturer.Deleted)
            {
                return(NotFound());
            }

            // Check whether the current user has a "Manage catalog" permission.
            // It allows him to preview a manufacturer before publishing.
            if (!manufacturer.Published && !await Services.Permissions.AuthorizeAsync(Permissions.Catalog.Manufacturer.Read))
            {
                return(NotFound());
            }

            // ACL (access control list).
            if (!await _aclService.AuthorizeAsync(manufacturer))
            {
                return(NotFound());
            }

            // Store mapping.
            if (!await _storeMappingService.AuthorizeAsync(manufacturer))
            {
                return(NotFound());
            }

            var customer = Services.WorkContext.CurrentCustomer;
            var storeId  = Services.StoreContext.CurrentStore.Id;

            // 'Continue shopping' URL.
            if (!customer.IsSystemAccount)
            {
                customer.GenericAttributes.LastContinueShoppingPage = Services.WebHelper.GetCurrentPageUrl(false);
            }

            var model = await _helper.PrepareBrandModelAsync(manufacturer);

            if (_seoSettings.CanonicalUrlsEnabled)
            {
                model.CanonicalUrl = _urlHelper.Value.RouteUrl("Manufacturer", new { model.SeName }, Request.Scheme);
            }

            if (query.IsSubPage && !_catalogSettings.ShowDescriptionInSubPages)
            {
                model.Description.ChangeValue(string.Empty);
                model.BottomDescription.ChangeValue(string.Empty);
            }

            model.Image = await _helper.PrepareBrandImageModelAsync(manufacturer, model.Name);

            // Featured products.
            var hideFeaturedProducts = _catalogSettings.IgnoreFeaturedProducts || (query.IsSubPage && !_catalogSettings.IncludeFeaturedProductsInSubPages);

            if (!hideFeaturedProducts)
            {
                CatalogSearchResult featuredProductsResult = null;

                var cacheKey = ModelCacheInvalidator.MANUFACTURER_HAS_FEATURED_PRODUCTS_KEY.FormatInvariant(manufacturerId, string.Join(",", customer.GetRoleIds()), storeId);
                var hasFeaturedProductsCache = await Services.Cache.GetAsync <bool?>(cacheKey);

                var featuredProductsQuery = new CatalogSearchQuery()
                                            .VisibleOnly(customer)
                                            .WithVisibility(ProductVisibility.Full)
                                            .WithManufacturerIds(true, manufacturerId)
                                            .HasStoreId(storeId)
                                            .WithLanguage(Services.WorkContext.WorkingLanguage)
                                            .WithCurrency(Services.WorkContext.WorkingCurrency);

                if (!hasFeaturedProductsCache.HasValue)
                {
                    featuredProductsResult = await _catalogSearchService.SearchAsync(featuredProductsQuery);

                    hasFeaturedProductsCache = featuredProductsResult.TotalHitsCount > 0;
                    await Services.Cache.PutAsync(cacheKey, hasFeaturedProductsCache);
                }

                if (hasFeaturedProductsCache.Value && featuredProductsResult == null)
                {
                    featuredProductsResult = await _catalogSearchService.SearchAsync(featuredProductsQuery);
                }

                if (featuredProductsResult != null)
                {
                    // TODO: (mc) determine settings properly
                    var featuredProductsmappingSettings = _helper.GetBestFitProductSummaryMappingSettings(ProductSummaryViewMode.Grid);
                    model.FeaturedProducts = await _helper.MapProductSummaryModelAsync(await featuredProductsResult.GetHitsAsync(), featuredProductsmappingSettings);
                }
            }

            // Products
            query.WithManufacturerIds(_catalogSettings.IncludeFeaturedProductsInNormalLists ? null : false, manufacturerId);

            var searchResult = await _catalogSearchService.SearchAsync(query);

            model.SearchResult = searchResult;

            var viewMode        = _helper.GetSearchQueryViewMode(query);
            var mappingSettings = _helper.GetBestFitProductSummaryMappingSettings(viewMode);

            model.Products = await _helper.MapProductSummaryModelAsync(await searchResult.GetHitsAsync(), mappingSettings);

            // Prepare paging/sorting/mode stuff
            _helper.MapListActions(model.Products, manufacturer, _catalogSettings.DefaultPageSizeOptions);

            // Template.
            var templateCacheKey = string.Format(ModelCacheInvalidator.MANUFACTURER_TEMPLATE_MODEL_KEY, manufacturer.ManufacturerTemplateId);
            var templateViewPath = await Services.Cache.GetAsync(templateCacheKey, async() =>
            {
                var template = await _db.ManufacturerTemplates.FindByIdAsync(manufacturer.ManufacturerTemplateId, false)
                               ?? await _db.ManufacturerTemplates.FirstOrDefaultAsync();

                return(template.ViewPath);
            });

            // Activity log.
            Services.ActivityLogger.LogActivity("PublicStore.ViewManufacturer", T("ActivityLog.PublicStore.ViewManufacturer"), manufacturer.Name);

            Services.DisplayControl.Announce(manufacturer);

            return(View(templateViewPath, model));
        }
        public async Task <CatalogSearchResult> SearchAsync(CatalogSearchCriteria criteria)
        {
            var retVal = new CatalogSearchResult();

            string sort      = "manual";
            string sortOrder = "asc";

            if (!string.IsNullOrEmpty(criteria.SortBy))
            {
                var splittedSortBy = criteria.SortBy.Split('-');
                if (splittedSortBy.Length > 1)
                {
                    sort      = splittedSortBy[0].Equals("title", StringComparison.OrdinalIgnoreCase) ? "name" : splittedSortBy[0];
                    sortOrder = splittedSortBy[1].IndexOf("descending", StringComparison.OrdinalIgnoreCase) >= 0 ? "desc" : "asc";
                }
            }

            var result = await _searchApi.SearchModuleSearchAsync(
                criteriaStoreId : _workContext.CurrentStore.Id,
                criteriaKeyword : criteria.Keyword,
                criteriaResponseGroup : criteria.ResponseGroup.ToString(),
                criteriaSearchInChildren : true,
                criteriaCategoryId : criteria.CategoryId,
                criteriaCatalogId : criteria.CatalogId,
                criteriaCurrency : _workContext.CurrentCurrency.Code,
                criteriaHideDirectLinkedCategories : true,
                criteriaTerms : criteria.Terms.ToStrings(),
                criteriaPricelistIds : _workContext.CurrentPriceListIds.ToList(),
                criteriaSkip : criteria.PageSize *(criteria.PageNumber - 1),
                criteriaTake : criteria.PageSize,
                criteriaSort : sort,
                criteriaSortOrder : sortOrder);

            if (criteria.CategoryId != null)
            {
                var category = await _catalogModuleApi.CatalogModuleCategoriesGetAsync(criteria.CategoryId);

                if (category != null)
                {
                    retVal.Category = category.ToWebModel();
                }
            }

            if (result != null)
            {
                if (result.Products != null && result.Products.Any())
                {
                    var products = result.Products.Select(x => x.ToWebModel(_workContext.CurrentLanguage, _workContext.CurrentCurrency)).ToArray();
                    retVal.Products = new StorefrontPagedList <Product>(products, criteria.PageNumber, criteria.PageSize, result.ProductsTotalCount.Value, page => _workContext.RequestUrl.SetQueryParameter("page", page.ToString()).ToString());

                    LoadProductsPrices(retVal.Products.ToArray());
                    LoadProductsInventories(retVal.Products.ToArray());
                }

                if (result.Categories != null && result.Categories.Any())
                {
                    retVal.Categories = result.Categories.Select(x => x.ToWebModel());
                }

                if (result.Aggregations != null)
                {
                    retVal.Aggregations = result.Aggregations.Select(x => x.ToWebModel()).ToArray();
                }
            }

            return(retVal);
        }
        public virtual async Task <ProductSummaryModel> MapProductSummaryModelAsync(IPagedList <Product> products, CatalogSearchResult sourceResult, ProductSummaryMappingSettings settings)
        {
            Guard.NotNull(products, nameof(products));

            if (settings == null)
            {
                settings = new ProductSummaryMappingSettings();
            }

            using (_services.Chronometer.Step("MapProductSummaryModel"))
            {
                var model = new ProductSummaryModel(products, sourceResult)
                {
                    ViewMode                          = settings.ViewMode,
                    GridColumnSpan                    = _catalogSettings.GridStyleListColumnSpan,
                    ShowSku                           = _catalogSettings.ShowProductSku,
                    ShowWeight                        = _catalogSettings.ShowWeight,
                    ShowDimensions                    = settings.MapDimensions,
                    ShowLegalInfo                     = settings.MapLegalInfo,
                    ShowDescription                   = settings.MapShortDescription,
                    ShowFullDescription               = settings.MapFullDescription,
                    ShowRatings                       = settings.MapReviews,
                    ShowPrice                         = settings.MapPrices,
                    ShowBasePrice                     = settings.MapPrices && _catalogSettings.ShowBasePriceInProductLists && settings.ViewMode != ProductSummaryViewMode.Mini,
                    ShowShippingSurcharge             = settings.MapPrices && settings.ViewMode != ProductSummaryViewMode.Mini,
                    ShowButtons                       = settings.ViewMode != ProductSummaryViewMode.Mini,
                    ShowBrand                         = settings.MapManufacturers,
                    ForceRedirectionAfterAddingToCart = settings.ForceRedirectionAfterAddingToCart,
                    CompareEnabled                    = _catalogSettings.CompareProductsEnabled,
                    WishlistEnabled                   = _services.Permissions.Authorize(Permissions.Cart.AccessWishlist),
                    BuyEnabled                        = !_catalogSettings.HideBuyButtonInLists,
                    ThumbSize                         = settings.ThumbnailSize,
                    ShowDiscountBadge                 = _catalogSettings.ShowDiscountSign,
                    ShowNewBadge                      = _catalogSettings.LabelAsNewForMaxDays.HasValue,
                    DeliveryTimesPresentation         = settings.DeliveryTimesPresentation,
                };

                if (products.Count == 0)
                {
                    // No products, stop here.
                    return(model);
                }

                using var scope = new DbContextScope(_db, retainConnection: true, deferCommit: true);

                // PERF!!
                var calculationOptions = _priceCalculationService.CreateDefaultOptions(true);
                var language           = calculationOptions.Language;
                var customer           = calculationOptions.Customer;
                var allowPrices        = await _services.Permissions.AuthorizeAsync(Permissions.Catalog.DisplayPrice);

                var allowShoppingCart = await _services.Permissions.AuthorizeAsync(Permissions.Cart.AccessShoppingCart);

                var allowWishlist = await _services.Permissions.AuthorizeAsync(Permissions.Cart.AccessWishlist);

                var cachedBrandModels    = new Dictionary <int, BrandOverviewModel>();
                var prefetchTranslations = settings.PrefetchTranslations == true || (settings.PrefetchTranslations == null && _performanceSettings.AlwaysPrefetchTranslations);
                var prefetchSlugs        = settings.PrefetchUrlSlugs == true || (settings.PrefetchUrlSlugs == null && _performanceSettings.AlwaysPrefetchUrlSlugs);
                var allProductIds        = prefetchSlugs || prefetchTranslations?products.Select(x => x.Id).ToArray() : Array.Empty <int>();

                //var productIds = products.Select(x => x.Id).ToArray();

                string taxInfo   = T(calculationOptions.TaxInclusive ? "Tax.InclVAT" : "Tax.ExclVAT");
                var    legalInfo = string.Empty;

                var res = new Dictionary <string, LocalizedString>(StringComparer.OrdinalIgnoreCase)
                {
                    { "Products.CallForPrice", T("Products.CallForPrice") },
                    { "Products.PriceRangeFrom", T("Products.PriceRangeFrom") },
                    { "Media.Product.ImageLinkTitleFormat", T("Media.Product.ImageLinkTitleFormat") },
                    { "Media.Product.ImageAlternateTextFormat", T("Media.Product.ImageAlternateTextFormat") },
                    { "Products.DimensionsValue", T("Products.DimensionsValue") },
                    { "Common.AdditionalShippingSurcharge", T("Common.AdditionalShippingSurcharge") }
                };

                if (settings.MapLegalInfo)
                {
                    var shippingInfoUrl = (await _urlHelper.TopicAsync("shippinginfo"));
                    legalInfo = shippingInfoUrl.HasValue()
                        ? T("Tax.LegalInfoShort", taxInfo, shippingInfoUrl)
                        : T("Tax.LegalInfoShort2", taxInfo);
                }

                if (prefetchSlugs)
                {
                    await _urlService.PrefetchUrlRecordsAsync(nameof(Product), new[] { language.Id, 0 }, allProductIds);
                }

                if (prefetchTranslations)
                {
                    // Prefetch all delivery time translations
                    await _localizedEntityService.PrefetchLocalizedPropertiesAsync(nameof(DeliveryTime), language.Id, null);
                }

                // Run in uncommitting scope, because pictures could be updated (IsNew property)
                var batchContext = _productService.CreateProductBatchContext(products, calculationOptions.Store, customer, false, true);

                if (settings.MapPrices)
                {
                    await batchContext.AppliedDiscounts.LoadAllAsync();

                    await batchContext.TierPrices.LoadAllAsync();
                }

                if (settings.MapAttributes || settings.MapColorAttributes)
                {
                    await batchContext.Attributes.LoadAllAsync();

                    if (prefetchTranslations)
                    {
                        // Prefetch all product attribute translations
                        await PrefetchTranslations(
                            nameof(ProductAttribute),
                            language.Id,
                            batchContext.Attributes.SelectMany(x => x.Value).Select(x => x.ProductAttribute));

                        // Prefetch all variant attribute value translations
                        await PrefetchTranslations(
                            nameof(ProductVariantAttributeValue),
                            language.Id,
                            batchContext.Attributes.SelectMany(x => x.Value).SelectMany(x => x.ProductVariantAttributeValues));
                    }
                }

                if (settings.MapManufacturers)
                {
                    await batchContext.ProductManufacturers.LoadAllAsync();
                }

                if (settings.MapSpecificationAttributes)
                {
                    await batchContext.SpecificationAttributes.LoadAllAsync();

                    if (prefetchTranslations)
                    {
                        // Prefetch all spec attribute option translations
                        await PrefetchTranslations(
                            nameof(SpecificationAttributeOption),
                            language.Id,
                            batchContext.SpecificationAttributes.SelectMany(x => x.Value).Select(x => x.SpecificationAttributeOption));

                        // Prefetch all spec attribute translations
                        await PrefetchTranslations(
                            nameof(SpecificationAttribute),
                            language.Id,
                            batchContext.SpecificationAttributes.SelectMany(x => x.Value).Select(x => x.SpecificationAttributeOption.SpecificationAttribute));
                    }
                }

                // If a size has been set in the view, we use it in priority
                int thumbSize = model.ThumbSize ?? _mediaSettings.ProductThumbPictureSize;

                calculationOptions.BatchContext = batchContext;

                // Don't perform discount limitation and coupon code check in list rendering as it can have heavy impact on performance.
                calculationOptions.CheckDiscountValidity = false;

                var mapItemContext = new MapProductSummaryItemContext
                {
                    BatchContext       = batchContext,
                    CalculationOptions = calculationOptions,
                    CachedBrandModels  = cachedBrandModels,
                    PrimaryCurrency    = _currencyService.PrimaryCurrency,
                    LegalInfo          = legalInfo,
                    Model                   = model,
                    Resources               = res,
                    MappingSettings         = settings,
                    AllowPrices             = allowPrices,
                    AllowShoppingCart       = allowShoppingCart,
                    AllowWishlist           = allowWishlist,
                    ShippingChargeTaxFormat = _currencyService.GetTaxFormat(priceIncludesTax: calculationOptions.TaxInclusive, target: PricingTarget.ShippingCharge, language: language),
                };

                if (settings.MapPictures)
                {
                    var fileIds = products
                                  .Select(x => x.MainPictureId ?? 0)
                                  .Where(x => x != 0)
                                  .Distinct()
                                  .ToArray();

                    mapItemContext.MediaFiles = (await _mediaService.GetFilesByIdsAsync(fileIds)).ToDictionarySafe(x => x.Id);
                }

                foreach (var product in products)
                {
                    await MapProductSummaryItem(product, mapItemContext);
                }

                _services.DisplayControl.AnnounceRange(products);

                await scope.CommitAsync();

                batchContext.Clear();

                // don't show stuff without data at all
                model.ShowDescription = model.ShowDescription && model.Items.Any(x => x.ShortDescription?.Value?.HasValue() == true);
                model.ShowBrand       = model.ShowBrand && model.Items.Any(x => x.Brand != null);

                return(model);
            }
        }
 public virtual async Task <ProductSummaryModel> MapProductSummaryModelAsync(CatalogSearchResult sourceResult, ProductSummaryMappingSettings settings)
 {
     return(await MapProductSummaryModelAsync(await sourceResult.GetHitsAsync(), sourceResult, settings));
 }