public override void OnActionExecuting(ActionExecutingContext filterContext) { if (_skipControllers.Any(x => filterContext.ActionDescriptor.ControllerDescriptor.ControllerType == x)) { return; } var context = filterContext.HttpContext; // don't 'rewrite' POST requests, child action and ajax requests if (context.Request.RequestType != "GET" || filterContext.IsChildAction || context.Request.IsAjaxRequest()) { return; } if (context.Request.Url != null) { var baseUri = string.Format( "{0}://{1}{2}", context.Request.Url.Scheme, context.Request.Url.Host, context.Request.Url.Port == 80 ? "" : ":" + context.Request.Url.Port); var path = HttpUtility.UrlDecode(string.Concat(baseUri, context.Request.Url.AbsolutePath)); if (!string.IsNullOrEmpty(path)) { var query = HttpUtility.UrlDecode(context.Request.Url.Query); var queryString = context.Request.QueryString; var needRedirect = false; //Make sure we allways use same virtual path as Route provides var routePath = filterContext.RouteData.Route.GetVirtualPath(filterContext.RequestContext, filterContext.RouteData.Values); if (routePath != null && !string.IsNullOrEmpty(routePath.VirtualPath)) { var absoluteRoutePath = HttpUtility.UrlDecode(string.Concat(baseUri, context.Request.ApplicationPath, context.Request.ApplicationPath != "/" ? "/" : "", routePath.VirtualPath)); if (!string.IsNullOrEmpty(absoluteRoutePath) && !absoluteRoutePath.Equals(path, StringComparison.InvariantCultureIgnoreCase)) { path = absoluteRoutePath; needRedirect = true; } } //Process query string if (!string.IsNullOrEmpty(query)) { //Rebuild querystring from scratch var newQuery = string.Empty; //First goes search filter ordered based on document var helper = new SearchHelper(StoreHelper.StoreClient.GetCurrentStore()); var urlHelper = new UrlHelper(context.Request.RequestContext); var parameters = helper.Filters.Where(f => !(f is PriceRangeFilter) || ((PriceRangeFilter)f).Currency.Equals(StoreHelper.CustomerSession.Currency, StringComparison.OrdinalIgnoreCase)) .Select(filter => queryString.AllKeys .FirstOrDefault(k => k.Equals(urlHelper.GetFacetKey(filter.Key), StringComparison.InvariantCultureIgnoreCase))) .Where(key => !string.IsNullOrEmpty(key)) .ToDictionary<string, string, object>(key => key, key => queryString[key]); if (parameters.Any()) { newQuery = urlHelper.SetQueryParameters(newQuery, parameters); } //Order remaining parameters var otherParams = queryString.AllKeys.Where(key => !parameters.ContainsKey(key)).OrderBy(k => k) .ToDictionary<string, string, object>(key => key, key => queryString[key]); if (otherParams.Any()) { newQuery = urlHelper.SetQueryParameters(newQuery, otherParams); } if (!string.IsNullOrEmpty(newQuery) && !newQuery.StartsWith("?")) { newQuery = string.Concat("?", newQuery); } newQuery = HttpUtility.UrlDecode(newQuery); if (!string.Equals(query, newQuery, StringComparison.InvariantCultureIgnoreCase)) { query = newQuery; needRedirect = true; } } //make language code allways be five symbols if (filterContext.RouteData.Values.ContainsKey(Routing.Constants.Language) && filterContext.RouteData.Values[Routing.Constants.Language] as string != null) { var lang = filterContext.RouteData.Values[Routing.Constants.Language].ToString(); if (lang.Length < 5) { try { var cult = CultureInfo.CreateSpecificCulture(lang); if (!path.ToLowerInvariant().Contains(cult.Name.ToLowerInvariant())) { path = path.Replace(lang, cult.Name); needRedirect = true; } } catch { //Something wrong with language?? } } } //make path segments allways encoded var encodedPath = path; encodedPath = ProcessSegment(filterContext.RouteData.Values, encodedPath, Routing.Constants.Store); encodedPath = ProcessSegment(filterContext.RouteData.Values, encodedPath, Routing.Constants.Category); encodedPath = ProcessSegment(filterContext.RouteData.Values, encodedPath, Routing.Constants.Item); // check for any upper-case letters: if (path != encodedPath.ToLowerInvariant()) { path = encodedPath.ToLowerInvariant(); needRedirect = true; } // make sure request ends with a "/" if (path.EndsWith("/")) { needRedirect = true; } if (needRedirect) { Redirect(context, path, query); return; } } } base.OnActionExecuting(filterContext); }
/// <summary> /// Gets the description from filter. /// </summary> /// <param name="helper">The helper.</param> /// <param name="key">The key.</param> /// <returns> /// System.String. /// </returns> private static string GetDescriptionFromFilter(SearchHelper helper, string key) { var name = helper.CatalogClient.GetPropertyName(key); return key.Equals("price", StringComparison.OrdinalIgnoreCase) ? "Price".Localize() : !string.IsNullOrEmpty(name) ? name : key; }
/// <summary> /// Gets the description from filter value. /// </summary> /// <param name="helper">The helper.</param> /// <param name="key">The key.</param> /// <param name="id">The identifier.</param> /// <returns> /// System.String. /// </returns> private static string GetDescriptionFromFilterValue(SearchHelper helper, string key, string id) { var desc = String.Empty; var d = (from f in helper.Filters where f.Key.Equals(key, StringComparison.OrdinalIgnoreCase) && (f as PriceRangeFilter == null || ((PriceRangeFilter)f).Currency.Equals(helper.CatalogClient.CustomerSession.Currency, StringComparison.OrdinalIgnoreCase)) select f).SingleOrDefault(); if (d != null) { var val = (from v in helper.GetFilterValues(d) where v.Id.Equals(id, StringComparison.OrdinalIgnoreCase) select v).SingleOrDefault(); if (val != null) { desc = Convert(helper, val).Name; } } return desc; }
/// <summary> /// Creates the data model. /// </summary> /// <param name="criteria">The criteria.</param> /// <param name="parameters">The parameters.</param> /// <param name="cacheResults">if set to <c>true</c> [cache results].</param> /// <returns>CatalogItemSearchModel.</returns> private CatalogItemSearchModel CreateDataModel(CatalogItemSearchCriteria criteria, SearchParameters parameters, bool cacheResults) { var session = UserHelper.CustomerSession; // Create a model var dataSource = new CatalogItemSearchModel(); // Now fill in filters var searchHelper = new SearchHelper(_storeClient.GetCurrentStore()); var filters = searchHelper.Filters; // Add all filters foreach (var filter in filters) { // Check if we already filtering if (parameters.Facets.Keys.Any(k => filter.Key.Equals(k, StringComparison.OrdinalIgnoreCase))) continue; criteria.Add(filter); } // Get selected filters var facets = parameters.Facets; dataSource.SelectedFilters = new List<SelectedFilterModel>(); if (facets.Count != 0) { foreach (var key in facets.Keys) { var filter = filters.SingleOrDefault(x => x.Key.Equals(key, StringComparison.OrdinalIgnoreCase) && (!(x is PriceRangeFilter) || ((PriceRangeFilter)x).Currency.Equals(StoreHelper.CustomerSession.Currency, StringComparison.OrdinalIgnoreCase))); var val = (from v in searchHelper.GetFilterValues(filter) where v.Id == facets[key] select v) .SingleOrDefault(); if (val != null) { criteria.Add(filter, val); dataSource.SelectedFilters.Add(new SelectedFilterModel(searchHelper.Convert(filter), searchHelper.Convert(val))); } } } // Perform search var sort = string.IsNullOrEmpty(parameters.Sort) ? "position" : parameters.Sort; var sortOrder = parameters.SortOrder; bool isDescending = "desc".Equals(sortOrder, StringComparison.OrdinalIgnoreCase); SearchSort sortObject = null; if (!sort.Equals("position", StringComparison.OrdinalIgnoreCase)) { if (sort.Equals("price", StringComparison.OrdinalIgnoreCase)) { if (session.Pricelists != null) { sortObject = new SearchSort(session.Pricelists.Select(priceList => new SearchSortField( String.Format("price_{0}_{1}", criteria.Currency.ToLower(), priceList.ToLower())) { IgnoredUnmapped = true, IsDescending = isDescending, DataType = SearchSortField.DOUBLE }) .ToArray()); } } else { sortObject = new SearchSort(sort.ToLower(), isDescending); } } // Put default sort order if none is set if (sortObject == null) { sortObject = CatalogItemSearchCriteria.DefaultSortOrder; } criteria.Sort = sortObject; CatalogItemSearchResults results; // Search using criteria, it will only return IDs of the items var items = Search(criteria, cacheResults, out results).ToArray(); var itemsIdsArray = items.Select(i => i.ItemId).ToArray(); // Now load items with appropriate var itemModelList = new List<CatalogItemWithPriceModel>(); if (items.Any()) { // Now convert it to the model var prices = _priceListClient.GetLowestPrices(session.Pricelists, itemsIdsArray, 1); var availabilities = _catalogClient.GetItemAvailability(itemsIdsArray, UserHelper.StoreClient.GetCurrentStore().FulfillmentCenterId); foreach (var item in items) { PriceModel priceModel = null; ItemAvailabilityModel availabilityModel = null; var catalogIdPath = UserHelper.CustomerSession.CatalogId + "/"; var searchTags = results.Items[item.ItemId.ToLower()].ToPropertyDictionary(); //Cache outline HttpContext.Items["browsingoutline_" + item.Code.ToLower()] = searchTags[criteria.BrowsingOutlineField].ToString(); var currentOutline = searchTags[criteria.OutlineField].ToString().Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) .FirstOrDefault(x => x.StartsWith(catalogIdPath, StringComparison.OrdinalIgnoreCase)) ?? string.Empty; if (prices != null && prices.Any()) { var lowestPrice = (from p in prices where p.ItemId.Equals(item.ItemId, StringComparison.OrdinalIgnoreCase) select p).SingleOrDefault(); if (lowestPrice != null) { var tags = new Hashtable { { "Outline", currentOutline } }; priceModel = _marketing.GetItemPriceModel(item, lowestPrice, tags); } } if (availabilities != null && availabilities.Any()) { var availability = (from a in availabilities where a.ItemId.Equals(item.ItemId, StringComparison.OrdinalIgnoreCase) select a).SingleOrDefault(); availabilityModel = new ItemAvailabilityModel(availability); } var itemModel = new CatalogItemWithPriceModel(CatalogHelper.CreateItemModel(item), priceModel, availabilityModel) { SearchOutline = currentOutline }; itemModelList.Add(itemModel); } } dataSource.FilterGroups = searchHelper.Convert(results.FacetGroups); dataSource.CatalogItems = itemModelList.ToArray(); dataSource.Criteria = criteria; // Create pager var pager = new PagerModel { TotalCount = results.TotalCount, CurrentPage = criteria.StartingRecord / criteria.RecordsToRetrieve + 1, RecordsPerPage = criteria.RecordsToRetrieve, StartingRecord = criteria.StartingRecord, DisplayStartingRecord = criteria.StartingRecord + 1, SortValues = new[] { "Position", "Name", "Price" }, SelectedSort = sort, SortOrder = isDescending ? "desc" : "asc" }; var end = criteria.StartingRecord + criteria.RecordsToRetrieve; pager.DisplayEndingRecord = end > results.TotalCount ? results.TotalCount : end; dataSource.Pager = pager; // Query similar words /* if (count == 0) dataSource.Suggestions = GetSuggestions(); * */ //} return dataSource; }