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)); }
public ActionResult Category(int categoryId, CatalogSearchQuery query) { var category = _categoryService.GetCategoryById(categoryId); if (category == null || category.Deleted) { return(HttpNotFound()); } // Check whether the current user has a "Manage catalog" permission // It allows him to preview a category before publishing if (!category.Published && !_services.Permissions.Authorize(StandardPermissionProvider.ManageCatalog)) { return(HttpNotFound()); } // ACL (access control list) if (!_aclService.Authorize(category)) { return(HttpNotFound()); } // Store mapping if (!_storeMappingService.Authorize(category)) { return(HttpNotFound()); } // 'Continue shopping' URL if (!_services.WorkContext.CurrentCustomer.IsSystemAccount) { _genericAttributeService.SaveAttribute(_services.WorkContext.CurrentCustomer, SystemCustomerAttributeNames.LastContinueShoppingPage, _services.WebHelper.GetThisPageUrl(false), _services.StoreContext.CurrentStore.Id); } var model = category.ToModel(); _services.DisplayControl.Announce(category); // Category breadcrumb if (_catalogSettings.CategoryBreadcrumbEnabled) { _helper.GetCategoryBreadCrumb(category.Id, 0).Select(x => x.Value).Each(x => _breadcrumb.Track(x)); } model.SubCategoryDisplayType = _catalogSettings.SubCategoryDisplayType; var customerRolesIds = _services.WorkContext.CurrentCustomer.CustomerRoles.Where(x => x.Active).Select(x => x.Id).ToList(); // subcategories model.SubCategories = _categoryService .GetAllCategoriesByParentCategoryId(categoryId) .Select(x => { var subCatName = x.GetLocalized(y => y.Name); var subCatModel = new CategoryModel.SubCategoryModel { Id = x.Id, Name = subCatName, SeName = x.GetSeName(), }; _services.DisplayControl.Announce(x); // prepare picture model int pictureSize = _mediaSettings.CategoryThumbPictureSize; var categoryPictureCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_PICTURE_MODEL_KEY, x.Id, pictureSize, true, _services.WorkContext.WorkingLanguage.Id, _services.StoreContext.CurrentStore.Id); subCatModel.PictureModel = _services.Cache.Get(categoryPictureCacheKey, () => { var picture = _pictureService.GetPictureById(x.PictureId.GetValueOrDefault()); var pictureModel = new PictureModel { PictureId = x.PictureId.GetValueOrDefault(), Size = pictureSize, FullSizeImageUrl = _pictureService.GetPictureUrl(picture), FullSizeImageWidth = picture?.Width, FullSizeImageHeight = picture?.Height, ImageUrl = _pictureService.GetPictureUrl(picture, pictureSize, !_catalogSettings.HideCategoryDefaultPictures), Title = string.Format(T("Media.Category.ImageLinkTitleFormat"), subCatName), AlternateText = string.Format(T("Media.Category.ImageAlternateTextFormat"), subCatName) }; return(pictureModel); }, TimeSpan.FromHours(6)); return(subCatModel); }) .ToList(); // Featured Products if (!_catalogSettings.IgnoreFeaturedProducts) { CatalogSearchResult featuredProductsResult = null; string cacheKey = ModelCacheEventConsumer.CATEGORY_HAS_FEATURED_PRODUCTS_KEY.FormatInvariant(categoryId, string.Join(",", customerRolesIds), _services.StoreContext.CurrentStore.Id); var hasFeaturedProductsCache = _services.Cache.Get <bool?>(cacheKey); var featuredProductsQuery = new CatalogSearchQuery() .VisibleOnly(_services.WorkContext.CurrentCustomer) .VisibleIndividuallyOnly(true) .WithCategoryIds(true, categoryId) .HasStoreId(_services.StoreContext.CurrentStore.Id) .WithLanguage(_services.WorkContext.WorkingLanguage) .WithCurrency(_services.WorkContext.WorkingCurrency); if (!hasFeaturedProductsCache.HasValue) { featuredProductsResult = _catalogSearchService.Search(featuredProductsQuery); hasFeaturedProductsCache = featuredProductsResult.TotalHitsCount > 0; _services.Cache.Put(cacheKey, hasFeaturedProductsCache, TimeSpan.FromHours(6)); } if (hasFeaturedProductsCache.Value && featuredProductsResult == null) { featuredProductsResult = _catalogSearchService.Search(featuredProductsQuery); } if (featuredProductsResult != null) { var featuredProductsmappingSettings = _helper.GetBestFitProductSummaryMappingSettings(ProductSummaryViewMode.Grid); model.FeaturedProducts = _helper.MapProductSummaryModel(featuredProductsResult.Hits, featuredProductsmappingSettings); } } // Products int[] catIds = new int[] { categoryId }; if (_catalogSettings.ShowProductsFromSubcategories) { // Include subcategories catIds = catIds.Concat(_helper.GetChildCategoryIds(categoryId)).ToArray(); } query.WithCategoryIds(_catalogSettings.IncludeFeaturedProductsInNormalLists ? (bool?)null : false, catIds); var searchResult = _catalogSearchService.Search(query); model.SearchResult = searchResult; var mappingSettings = _helper.GetBestFitProductSummaryMappingSettings(query.GetViewMode()); model.Products = _helper.MapProductSummaryModel(searchResult.Hits, mappingSettings); // Prepare paging/sorting/mode stuff _helper.MapListActions(model.Products, category, _catalogSettings.DefaultPageSizeOptions); // template var templateCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_TEMPLATE_MODEL_KEY, category.CategoryTemplateId); var templateViewPath = _services.Cache.Get(templateCacheKey, () => { var template = _categoryTemplateService.GetCategoryTemplateById(category.CategoryTemplateId); if (template == null) { template = _categoryTemplateService.GetAllCategoryTemplates().FirstOrDefault(); } return(template.ViewPath); }); // Activity log _services.CustomerActivity.InsertActivity("PublicStore.ViewCategory", T("ActivityLog.PublicStore.ViewCategory"), category.Name); return(View(templateViewPath, model)); }
public 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)); }
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)); }
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)); }
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)); }