예제 #1
0
        public async Task <SearchModel> Handle(GetSearch request, CancellationToken cancellationToken)
        {
            if (request.Model == null)
            {
                request.Model = new SearchModel();
            }

            var searchTerms = request.Model.q;

            if (searchTerms == null)
            {
                searchTerms = "";
            }
            searchTerms = searchTerms.Trim();

            if (request.Model.Box)
            {
                request.Model.sid = _catalogSettings.SearchByDescription;
            }
            if (request.Model.sid)
            {
                request.Model.adv = true;
            }

            //view/sorting/page size
            var options = await _mediator.Send(new GetViewSortSizeOptions()
            {
                Command = request.Command,
                PagingFilteringModel           = request.Model.PagingFilteringContext,
                Language                       = request.Language,
                AllowCustomersToSelectPageSize = _catalogSettings.SearchPageAllowCustomersToSelectPageSize,
                PageSizeOptions                = _catalogSettings.SearchPagePageSizeOptions,
                PageSize                       = _catalogSettings.SearchPageProductsPerPage
            });

            request.Model.PagingFilteringContext = options.pagingFilteringModel;
            request.Command = options.command;


            string cacheKey = string.Format(CacheKeyConst.SEARCH_CATEGORIES_MODEL_KEY,
                                            request.Language.Id,
                                            string.Join(",", request.Customer.GetCustomerGroupIds()),
                                            request.Store.Id);
            var categories = await _cacheBase.GetAsync(cacheKey, async() =>
            {
                var categoriesModel = new List <SearchModel.CategoryModel>();
                //all categories
                var allCategories = await _categoryService.GetAllCategories(parentId: "", storeId: request.Store.Id);
                foreach (var c in allCategories)
                {
                    //generate full category name (breadcrumb)
                    string categoryBreadcrumb = "";
                    var breadcrumb            = _categoryService.GetCategoryBreadCrumb(c, allCategories);
                    for (int i = 0; i <= breadcrumb.Count - 1; i++)
                    {
                        categoryBreadcrumb += breadcrumb[i].GetTranslation(x => x.Name, request.Language.Id);
                        if (i != breadcrumb.Count - 1)
                        {
                            categoryBreadcrumb += " >> ";
                        }
                    }
                    categoriesModel.Add(new SearchModel.CategoryModel
                    {
                        Id         = c.Id,
                        Breadcrumb = categoryBreadcrumb
                    });
                }
                return(categoriesModel);
            });

            if (categories.Any())
            {
                //first empty entry
                request.Model.AvailableCategories.Add(new SelectListItem
                {
                    Value = "",
                    Text  = _translationService.GetResource("Common.All")
                });
                //all other categories
                foreach (var c in categories)
                {
                    request.Model.AvailableCategories.Add(new SelectListItem
                    {
                        Value    = c.Id.ToString(),
                        Text     = c.Breadcrumb,
                        Selected = request.Model.cid == c.Id
                    });
                }
            }

            var collections = await _collectionService.GetAllCollections();

            if (collections.Any())
            {
                request.Model.AvailableCollections.Add(new SelectListItem
                {
                    Value = "",
                    Text  = _translationService.GetResource("Common.All")
                });
                foreach (var m in collections)
                {
                    request.Model.AvailableCollections.Add(new SelectListItem
                    {
                        Value    = m.Id.ToString(),
                        Text     = m.GetTranslation(x => x.Name, request.Language.Id),
                        Selected = request.Model.mid == m.Id
                    });
                }
            }

            request.Model.asv = _vendorSettings.AllowSearchByVendor;
            if (request.Model.asv)
            {
                var vendors = await _vendorService.GetAllVendors();

                if (vendors.Any())
                {
                    request.Model.AvailableVendors.Add(new SelectListItem
                    {
                        Value = "",
                        Text  = _translationService.GetResource("Common.All")
                    });
                    foreach (var vendor in vendors)
                    {
                        request.Model.AvailableVendors.Add(new SelectListItem
                        {
                            Value    = vendor.Id.ToString(),
                            Text     = vendor.GetTranslation(x => x.Name, request.Language.Id),
                            Selected = request.Model.vid == vendor.Id
                        });
                    }
                }
            }

            IPagedList <Product> products = new PagedList <Product>(new List <Product>(), 0, 1);

            if (request.IsSearchTermSpecified)
            {
                if (searchTerms.Length < _catalogSettings.ProductSearchTermMinimumLength)
                {
                    request.Model.Warning = string.Format(_translationService.GetResource("Search.SearchTermMinimumLengthIsNCharacters"), _catalogSettings.ProductSearchTermMinimumLength);
                }
                else
                {
                    var    categoryIds          = new List <string>();
                    string collectionId         = "";
                    double?minPriceConverted    = null;
                    double?maxPriceConverted    = null;
                    bool   searchInDescriptions = false;
                    string vendorId             = "";
                    if (request.Model.adv)
                    {
                        //advanced search
                        var categoryId = request.Model.cid;
                        if (!String.IsNullOrEmpty(categoryId))
                        {
                            categoryIds.Add(categoryId);
                            //include subcategories
                            categoryIds.AddRange(await _mediator.Send(new GetChildCategoryIds()
                            {
                                ParentCategoryId = categoryId, Customer = request.Customer, Store = request.Store
                            }));
                        }
                        collectionId = request.Model.mid;

                        //min price
                        if (!string.IsNullOrEmpty(request.Model.pf))
                        {
                            double minPrice;
                            if (double.TryParse(request.Model.pf, out minPrice))
                            {
                                minPriceConverted = await _currencyService.ConvertToPrimaryStoreCurrency(minPrice, request.Currency);
                            }
                        }
                        //max price
                        if (!string.IsNullOrEmpty(request.Model.pt))
                        {
                            double maxPrice;
                            if (double.TryParse(request.Model.pt, out maxPrice))
                            {
                                maxPriceConverted = await _currencyService.ConvertToPrimaryStoreCurrency(maxPrice, request.Currency);
                            }
                        }

                        searchInDescriptions = request.Model.sid;
                        if (request.Model.asv)
                        {
                            vendorId = request.Model.vid;
                        }
                    }

                    var searchInProductTags = searchInDescriptions;

                    IList <string> alreadyFilteredSpecOptionIds = await request.Model.PagingFilteringContext.SpecificationFilter.GetAlreadyFilteredSpecOptionIds
                                                                      (_httpContextAccessor, _specificationAttributeService);

                    //products
                    var searchproducts = (await _mediator.Send(new GetSearchProductsQuery()
                    {
                        LoadFilterableSpecificationAttributeOptionIds = !_catalogSettings.IgnoreFilterableSpecAttributeOption,
                        CategoryIds = categoryIds,
                        CollectionId = collectionId,
                        Customer = request.Customer,
                        StoreId = request.Store.Id,
                        VisibleIndividuallyOnly = true,
                        PriceMin = minPriceConverted,
                        PriceMax = maxPriceConverted,
                        Keywords = searchTerms,
                        SearchDescriptions = searchInDescriptions,
                        SearchSku = searchInDescriptions,
                        SearchProductTags = searchInProductTags,
                        FilteredSpecs = alreadyFilteredSpecOptionIds,
                        LanguageId = request.Language.Id,
                        OrderBy = (ProductSortingEnum)request.Command.OrderBy,
                        PageIndex = request.Command.PageNumber - 1,
                        PageSize = request.Command.PageSize,
                        VendorId = vendorId
                    }));

                    request.Model.Products = (await _mediator.Send(new GetProductOverview()
                    {
                        Products = searchproducts.products,
                        PrepareSpecificationAttributes = _catalogSettings.ShowSpecAttributeOnCatalogPages
                    })).ToList();

                    request.Model.PagingFilteringContext.LoadPagedList(searchproducts.products);

                    //specs
                    await request.Model.PagingFilteringContext.SpecificationFilter.PrepareSpecsFilters(alreadyFilteredSpecOptionIds,
                                                                                                       searchproducts.filterableSpecificationAttributeOptionIds,
                                                                                                       _specificationAttributeService, _httpContextAccessor, _cacheBase, request.Language.Id);

                    request.Model.NoResults = !request.Model.Products.Any();

                    //search term statistics
                    if (!String.IsNullOrEmpty(searchTerms))
                    {
                        var searchTerm = await _searchTermService.GetSearchTermByKeyword(searchTerms, request.Store.Id);

                        if (searchTerm != null)
                        {
                            searchTerm.Count++;
                            await _searchTermService.UpdateSearchTerm(searchTerm);
                        }
                        else
                        {
                            searchTerm = new SearchTerm
                            {
                                Keyword = searchTerms,
                                StoreId = request.Store.Id,
                                Count   = 1
                            };
                            await _searchTermService.InsertSearchTerm(searchTerm);
                        }
                    }
                }
            }

            return(request.Model);
        }
예제 #2
0
        public async Task <IList <SearchAutoCompleteModel> > Handle(GetSearchAutoComplete request, CancellationToken cancellationToken)
        {
            var model         = new List <SearchAutoCompleteModel>();
            var productNumber = _catalogSettings.ProductSearchAutoCompleteNumberOfProducts > 0 ?
                                _catalogSettings.ProductSearchAutoCompleteNumberOfProducts : 10;
            var storeId     = request.Store.Id;
            var categoryIds = new List <string>();

            if (!string.IsNullOrEmpty(request.CategoryId))
            {
                categoryIds.Add(request.CategoryId);
                if (_catalogSettings.ShowProductsFromSubcategoriesInSearchBox)
                {
                    //include subcategories
                    categoryIds.AddRange(await _mediator.Send(new GetChildCategoryIds()
                    {
                        ParentCategoryId = request.CategoryId, Customer = request.Customer, Store = request.Store
                    }));
                }
            }

            var products = (await _mediator.Send(new GetSearchProductsQuery()
            {
                Customer = request.Customer,
                StoreId = storeId,
                Keywords = request.Term,
                CategoryIds = categoryIds,
                SearchSku = _catalogSettings.SearchBySku,
                SearchDescriptions = _catalogSettings.SearchByDescription,
                LanguageId = request.Language.Id,
                VisibleIndividuallyOnly = true,
                PageSize = productNumber
            })).products;

            var categories    = new List <string>();
            var manufacturers = new List <string>();

            var storeurl = _webHelper.GetStoreLocation();

            foreach (var item in products)
            {
                var pictureUrl = "";
                if (_catalogSettings.ShowProductImagesInSearchAutoComplete)
                {
                    var picture = item.ProductPictures.OrderBy(x => x.DisplayOrder).FirstOrDefault();
                    if (picture != null)
                    {
                        pictureUrl = await _pictureService.GetPictureUrl(picture.PictureId, _mediaSettings.AutoCompleteSearchThumbPictureSize);
                    }
                }
                var rating = await _mediator.Send(new GetProductReviewOverview()
                {
                    Language = request.Language,
                    Product  = item,
                    Store    = request.Store
                });

                var price = await PreparePrice(item, request);

                model.Add(new SearchAutoCompleteModel()
                {
                    SearchType           = "Product",
                    Label                = item.GetLocalized(x => x.Name, request.Language.Id) ?? "",
                    Desc                 = item.GetLocalized(x => x.ShortDescription, request.Language.Id) ?? "",
                    PictureUrl           = pictureUrl,
                    AllowCustomerReviews = rating.AllowCustomerReviews,
                    Rating               = rating.TotalReviews > 0 ? (((rating.RatingSum * 100) / rating.TotalReviews) / 5) : 0,
                    Price                = price.Price,
                    PriceWithDiscount    = price.PriceWithDiscount,
                    Url = $"{storeurl}{item.SeName}"
                });
                foreach (var category in item.ProductCategories)
                {
                    categories.Add(category.CategoryId);
                }
                foreach (var manufacturer in item.ProductManufacturers)
                {
                    manufacturers.Add(manufacturer.ManufacturerId);
                }
            }

            foreach (var item in manufacturers.Distinct())
            {
                var manufacturer = await _manufacturerService.GetManufacturerById(item);

                if (manufacturer != null && manufacturer.Published)
                {
                    var allow = true;
                    if (!_catalogSettings.IgnoreAcl)
                    {
                        if (!_aclService.Authorize(manufacturer))
                        {
                            allow = false;
                        }
                    }
                    if (!_catalogSettings.IgnoreStoreLimitations)
                    {
                        if (!_storeMappingService.Authorize(manufacturer))
                        {
                            allow = false;
                        }
                    }
                    if (allow)
                    {
                        var desc = "";
                        if (_catalogSettings.SearchByDescription)
                        {
                            desc = "&sid=true";
                        }
                        model.Add(new SearchAutoCompleteModel()
                        {
                            SearchType = "Manufacturer",
                            Label      = manufacturer.GetLocalized(x => x.Name, request.Language.Id),
                            Desc       = "",
                            PictureUrl = "",
                            Url        = $"{storeurl}search?q={request.Term}&adv=true&mid={item}{desc}"
                        });
                    }
                }
            }
            foreach (var item in categories.Distinct())
            {
                var category = await _categoryService.GetCategoryById(item);

                if (category != null && category.Published)
                {
                    var allow = true;
                    if (!_catalogSettings.IgnoreAcl)
                    {
                        if (!_aclService.Authorize(category))
                        {
                            allow = false;
                        }
                    }
                    if (!_catalogSettings.IgnoreStoreLimitations)
                    {
                        if (!_storeMappingService.Authorize(category))
                        {
                            allow = false;
                        }
                    }
                    if (allow)
                    {
                        var desc = "";
                        if (_catalogSettings.SearchByDescription)
                        {
                            desc = "&sid=true";
                        }
                        model.Add(new SearchAutoCompleteModel()
                        {
                            SearchType = "Category",
                            Label      = category.GetLocalized(x => x.Name, request.Language.Id),
                            Desc       = "",
                            PictureUrl = "",
                            Url        = $"{storeurl}search?q={request.Term}&adv=true&cid={item}{desc}"
                        });
                    }
                }
            }

            if (_blogSettings.ShowBlogPostsInSearchAutoComplete)
            {
                var posts = await _blogService.GetAllBlogPosts(storeId : storeId, pageSize : productNumber, blogPostName : request.Term);

                foreach (var item in posts)
                {
                    model.Add(new SearchAutoCompleteModel()
                    {
                        SearchType = "Blog",
                        Label      = item.GetLocalized(x => x.Title, request.Language.Id),
                        Desc       = "",
                        PictureUrl = "",
                        Url        = $"{storeurl}{item.SeName}"
                    });
                }
            }
            //search term statistics
            if (!String.IsNullOrEmpty(request.Term) && _catalogSettings.SaveSearchAutoComplete)
            {
                var searchTerm = await _searchTermService.GetSearchTermByKeyword(request.Term, request.Store.Id);

                if (searchTerm != null)
                {
                    searchTerm.Count++;
                    await _searchTermService.UpdateSearchTerm(searchTerm);
                }
                else
                {
                    searchTerm = new SearchTerm {
                        Keyword = request.Term,
                        StoreId = storeId,
                        Count   = 1
                    };
                    await _searchTermService.InsertSearchTerm(searchTerm);
                }
            }
            return(model);
        }
예제 #3
0
        public override SearchModel PrepareSearchModel(SearchModel model, CatalogPagingFilteringModel command)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            var searchTerms = model.q ?? string.Empty;

            searchTerms = searchTerms.Trim();

            //sorting
            PrepareSortingOptions(model.PagingFilteringContext, command);
            //view mode
            PrepareViewModes(model.PagingFilteringContext, command);
            //page size
            PreparePageSizeOptions(model.PagingFilteringContext, command,
                                   _catalogSettings.SearchPageAllowCustomersToSelectPageSize,
                                   _catalogSettings.SearchPagePageSizeOptions,
                                   _catalogSettings.SearchPageProductsPerPage);


            var categoriesModels = new List <SearchModel.CategoryModel>();
            //all categories
            var allCategories = _categoryService.GetAllCategories(storeId: _storeContext.CurrentStore.Id);

            foreach (var c in allCategories)
            {
                //generate full category name (breadcrumb)
                var categoryBreadcrumb = string.Empty;
                var breadcrumb         = _categoryService.GetCategoryBreadCrumb(c, allCategories);
                for (var i = 0; i <= breadcrumb.Count - 1; i++)
                {
                    categoryBreadcrumb += _localizationService.GetLocalized(breadcrumb[i], x => x.Name);
                    if (i != breadcrumb.Count - 1)
                    {
                        categoryBreadcrumb += " >> ";
                    }
                }

                categoriesModels.Add(new SearchModel.CategoryModel
                {
                    Id         = c.Id,
                    Breadcrumb = categoryBreadcrumb
                });
            }

            if (categoriesModels.Any())
            {
                //first empty entry
                model.AvailableCategories.Add(new SelectListItem
                {
                    Value = "0",
                    Text  = _localizationService.GetResource("Common.All")
                });
                //all other categories
                foreach (var c in categoriesModels)
                {
                    model.AvailableCategories.Add(new SelectListItem
                    {
                        Value    = c.Id.ToString(),
                        Text     = c.Breadcrumb,
                        Selected = model.cid == c.Id
                    });
                }
            }

            var manufacturers = _manufacturerService.GetAllManufacturers(storeId: _storeContext.CurrentStore.Id);

            if (manufacturers.Any())
            {
                model.AvailableManufacturers.Add(new SelectListItem
                {
                    Value = "0",
                    Text  = _localizationService.GetResource("Common.All")
                });
                foreach (var m in manufacturers)
                {
                    model.AvailableManufacturers.Add(new SelectListItem
                    {
                        Value    = m.Id.ToString(),
                        Text     = _localizationService.GetLocalized(m, x => x.Name),
                        Selected = model.mid == m.Id
                    });
                }
            }

            model.asv = _vendorSettings.AllowSearchByVendor;
            if (model.asv)
            {
                var vendors = _vendorService.GetAllVendors();
                if (vendors.Any())
                {
                    model.AvailableVendors.Add(new SelectListItem
                    {
                        Value = "0",
                        Text  = _localizationService.GetResource("Common.All")
                    });
                    foreach (var vendor in vendors)
                    {
                        model.AvailableVendors.Add(new SelectListItem
                        {
                            Value    = vendor.Id.ToString(),
                            Text     = _localizationService.GetLocalized(vendor, x => x.Name),
                            Selected = model.vid == vendor.Id
                        });
                    }
                }
            }

            IPagedList <Product> products = new PagedList <Product>(new List <Product>(), 0, 1);
            // only search if query string search keyword is set (used to avoid searching or displaying search term min length error message on /search page load)
            //we don't use "!string.IsNullOrEmpty(searchTerms)" in cases of "ProductSearchTermMinimumLength" set to 0 but searching by other parameters (e.g. category or price filter)
            var isSearchTermSpecified = _httpContextAccessor.HttpContext.Request.Query.ContainsKey("q");

            if (isSearchTermSpecified)
            {
                if (searchTerms.Length < _catalogSettings.ProductSearchTermMinimumLength)
                {
                    model.Warning = string.Format(_localizationService.GetResource("Search.SearchTermMinimumLengthIsNCharacters"), _catalogSettings.ProductSearchTermMinimumLength);
                }
                else
                {
                    var     categoryIds          = new List <int>();
                    var     manufacturerId       = 0;
                    decimal?minPriceConverted    = null;
                    decimal?maxPriceConverted    = null;
                    var     searchInDescriptions = false;
                    var     vendorId             = 0;
                    if (model.adv)
                    {
                        //advanced search
                        var categoryId = model.cid;
                        if (categoryId > 0)
                        {
                            categoryIds.Add(categoryId);
                            if (model.isc)
                            {
                                //include subcategories
                                categoryIds.AddRange(_categoryService.GetChildCategoryIds(categoryId, _storeContext.CurrentStore.Id));
                            }
                        }

                        manufacturerId = model.mid;

                        //min price
                        if (!string.IsNullOrEmpty(model.pf))
                        {
                            if (decimal.TryParse(model.pf, out decimal minPrice))
                            {
                                minPriceConverted = _currencyService.ConvertToPrimaryStoreCurrency(minPrice, _workContext.WorkingCurrency);
                            }
                        }
                        //max price
                        if (!string.IsNullOrEmpty(model.pt))
                        {
                            if (decimal.TryParse(model.pt, out decimal maxPrice))
                            {
                                maxPriceConverted = _currencyService.ConvertToPrimaryStoreCurrency(maxPrice, _workContext.WorkingCurrency);
                            }
                        }

                        if (model.asv)
                        {
                            vendorId = model.vid;
                        }

                        searchInDescriptions = model.sid;
                    }

                    //var searchInProductTags = false;
                    var searchInProductTags = searchInDescriptions;

                    ///////////////////////////////////////////////////////
                    ////// Lucene Search //////////////////////////////////
                    ///////////////////////////////////////////////////////
                    if (_luceneSettings.Enabled)
                    {
                        _luceneService.GetLuceneDirectory();

                        var luceneProducts = _luceneService.Search(model.q);

                        products = new PagedList <Product>(luceneProducts.AsQueryable(), command.PageNumber - 1, command.PageSize);
                    }
                    else
                    {
                        //products
                        products = _productService.SearchProducts(
                            categoryIds: categoryIds,
                            manufacturerId: manufacturerId,
                            storeId: _storeContext.CurrentStore.Id,
                            visibleIndividuallyOnly: true,
                            priceMin: minPriceConverted,
                            priceMax: maxPriceConverted,
                            keywords: searchTerms,
                            searchDescriptions: searchInDescriptions,
                            searchProductTags: searchInProductTags,
                            languageId: _workContext.WorkingLanguage.Id,
                            orderBy: (ProductSortingEnum)command.OrderBy,
                            pageIndex: command.PageNumber - 1,
                            pageSize: command.PageSize,
                            vendorId: vendorId);
                    }
                    //////////////////////////////////////////////////////////

                    model.Products = _productModelFactory.PrepareProductOverviewModels(products).ToList();

                    model.NoResults = !model.Products.Any();

                    //search term statistics
                    if (!string.IsNullOrEmpty(searchTerms))
                    {
                        var searchTerm = _searchTermService.GetSearchTermByKeyword(searchTerms, _storeContext.CurrentStore.Id);
                        if (searchTerm != null)
                        {
                            searchTerm.Count++;
                            _searchTermService.UpdateSearchTerm(searchTerm);
                        }
                        else
                        {
                            searchTerm = new SearchTerm
                            {
                                Keyword = searchTerms,
                                StoreId = _storeContext.CurrentStore.Id,
                                Count   = 1
                            };
                            _searchTermService.InsertSearchTerm(searchTerm);
                        }
                    }

                    //event
                    _eventPublisher.Publish(new ProductSearchEvent
                    {
                        SearchTerm           = searchTerms,
                        SearchInDescriptions = searchInDescriptions,
                        CategoryIds          = categoryIds,
                        ManufacturerId       = manufacturerId,
                        WorkingLanguageId    = _workContext.WorkingLanguage.Id,
                        VendorId             = vendorId
                    });
                }
            }

            model.PagingFilteringContext.LoadPagedList(products);
            return(model);
        }
예제 #4
0
        public virtual SearchModel PrepareSearchModel(SearchModel model, CatalogPagingFilteringModel command)
        {
            if (model == null)
            {
                throw new ArgumentNullException("model");
            }

            var searchTerms = model.q;

            if (searchTerms == null)
            {
                searchTerms = "";
            }
            searchTerms = searchTerms.Trim();


            //sorting
            PrepareSortingOptions(model.PagingFilteringContext, command);
            //view mode
            PrepareViewModes(model.PagingFilteringContext, command);
            //page size
            PreparePageSizeOptions(model.PagingFilteringContext, command,
                                   _catalogSettings.SearchPageAllowCustomersToSelectPageSize,
                                   _catalogSettings.SearchPagePageSizeOptions,
                                   _catalogSettings.SearchPageProductsPerPage);


            string cacheKey = string.Format(ModelCacheEventConsumer.SEARCH_CATEGORIES_MODEL_KEY,
                                            _workContext.WorkingLanguage.Id,
                                            string.Join(",", _workContext.CurrentCustomer.GetCustomerRoleIds()),
                                            _storeContext.CurrentStore.Id);
            var categories = _cacheManager.Get(cacheKey, () =>
            {
                var categoriesModel = new List <SearchModel.CategoryModel>();
                //all categories
                var allCategories = _categoryService.GetAllCategories(storeId: _storeContext.CurrentStore.Id);
                foreach (var c in allCategories)
                {
                    //generate full category name (breadcrumb)
                    string categoryBreadcrumb = "";
                    var breadcrumb            = c.GetCategoryBreadCrumb(allCategories, _aclService, _storeMappingService);
                    for (int i = 0; i <= breadcrumb.Count - 1; i++)
                    {
                        categoryBreadcrumb += breadcrumb[i].GetLocalized(x => x.Name);
                        if (i != breadcrumb.Count - 1)
                        {
                            categoryBreadcrumb += " >> ";
                        }
                    }
                    categoriesModel.Add(new SearchModel.CategoryModel
                    {
                        Id         = c.Id,
                        Breadcrumb = categoryBreadcrumb
                    });
                }
                return(categoriesModel);
            });

            if (categories.Any())
            {
                //first empty entry
                model.AvailableCategories.Add(new SelectListItem
                {
                    Value = "0",
                    Text  = _localizationService.GetResource("Common.All")
                });
                //all other categories
                foreach (var c in categories)
                {
                    model.AvailableCategories.Add(new SelectListItem
                    {
                        Value    = c.Id.ToString(),
                        Text     = c.Breadcrumb,
                        Selected = model.cid == c.Id
                    });
                }
            }

            IPagedList <Product> products = new PagedList <Product>(new List <Product>(), 0, 1);
            var isSearchTermSpecified     = false;

            try
            {
                // only search if query string search keyword is set (used to avoid searching or displaying search term min length error message on /search page load)
                isSearchTermSpecified = _httpContext.Request.Params["q"] != null;
            }
            catch
            {
                //the "A potentially dangerous Request.QueryString value was detected from the client" exception could be thrown here when some wrong char is specified (e.g. <)
                //although we [ValidateInput(false)] attribute here we try to access "Request.Params" directly
                //that's why we do not re-throw it

                //just ensure that some search term is specified (0 length is not supported inthis case)
                isSearchTermSpecified = !String.IsNullOrEmpty(searchTerms);
            }
            if (isSearchTermSpecified)
            {
                if (searchTerms.Length < _catalogSettings.ProductSearchTermMinimumLength)
                {
                    model.Warning = string.Format(_localizationService.GetResource("Search.SearchTermMinimumLengthIsNCharacters"), _catalogSettings.ProductSearchTermMinimumLength);
                }
                else
                {
                    var  categoryIds          = new List <int>();
                    bool searchInDescriptions = false;
                    if (model.adv)
                    {
                        //advanced search
                        var categoryId = model.cid;
                        if (categoryId > 0)
                        {
                            categoryIds.Add(categoryId);
                            if (model.isc)
                            {
                                //include subcategories
                                categoryIds.AddRange(GetChildCategoryIds(categoryId));
                            }
                        }

                        searchInDescriptions = model.sid;
                    }

                    //var searchInProductTags = false;
                    var searchInProductTags = searchInDescriptions;

                    //products
                    products = _productService.SearchProducts(
                        categoryIds: categoryIds,
                        storeId: _storeContext.CurrentStore.Id,
                        visibleIndividuallyOnly: true,
                        keywords: searchTerms,
                        searchDescriptions: searchInDescriptions,
                        searchProductTags: searchInProductTags,
                        languageId: _workContext.WorkingLanguage.Id,
                        orderBy: (ProductSortingEnum)command.OrderBy,
                        pageIndex: command.PageNumber - 1,
                        pageSize: command.PageSize);
                    model.Products = _productModelFactory.PrepareProductOverviewModels(products).ToList();

                    model.NoResults = !model.Products.Any();

                    //search term statistics
                    if (!String.IsNullOrEmpty(searchTerms))
                    {
                        var searchTerm = _searchTermService.GetSearchTermByKeyword(searchTerms, _storeContext.CurrentStore.Id);
                        if (searchTerm != null)
                        {
                            searchTerm.Count++;
                            _searchTermService.UpdateSearchTerm(searchTerm);
                        }
                        else
                        {
                            searchTerm = new SearchTerm
                            {
                                Keyword = searchTerms,
                                StoreId = _storeContext.CurrentStore.Id,
                                Count   = 1
                            };
                            _searchTermService.InsertSearchTerm(searchTerm);
                        }
                    }

                    //event
                    _eventPublisher.Publish(new ProductSearchEvent
                    {
                        SearchTerm           = searchTerms,
                        SearchInDescriptions = searchInDescriptions,
                        CategoryIds          = categoryIds,
                        WorkingLanguageId    = _workContext.WorkingLanguage.Id,
                    });
                }
            }

            model.PagingFilteringContext.LoadPagedList(products);
            return(model);
        }
예제 #5
0
 /// <summary>
 /// Updates the search term record
 /// </summary>
 /// <param name="searchTerm">Search term</param>
 public void UpdateSearchTerm(SearchTerm searchTerm)
 {
     _searchTermService.UpdateSearchTerm(searchTerm);
 }