public virtual T AsCriteria <T>(string storeId, string catalog, ISearchFilter[] filters) where T : CatalogItemSearchCriteria, new() { var criteria = AbstractTypeFactory <T> .TryCreateInstance(); criteria.Ids = ProductIds; criteria.Currency = Currency; criteria.Pricelists = PriceLists; criteria.SearchPhrase = SearchPhrase; criteria.Locale = Locale; criteria.StartingRecord = Skip; criteria.RecordsToRetrieve = Take; // add outline if (!string.IsNullOrEmpty(Outline)) { criteria.Outlines.Add(string.Join("/", catalog, Outline)); } else { criteria.Outlines.Add(catalog ?? string.Empty); } // Add all filters foreach (var filter in filters) { criteria.Add(filter); } #region Filters var terms = Terms.AsKeyValues(); if (terms.Any()) { var filtersWithValues = filters .Where(x => (!(x is PriceRangeFilter) || ((PriceRangeFilter)x).Currency.Equals(Currency, StringComparison.OrdinalIgnoreCase))) .Select(x => new { Filter = x, Values = x.GetValues() }) .ToList(); foreach (var term in terms) { var filter = filters.SingleOrDefault(x => x.Key.Equals(term.Key, StringComparison.OrdinalIgnoreCase) && (!(x is PriceRangeFilter) || ((PriceRangeFilter)x).Currency.Equals(criteria.Currency, StringComparison.OrdinalIgnoreCase))); // handle special filter term with a key = "tags", it contains just values and we need to determine which filter to use if (filter == null && term.Key == "tags") { foreach (var termValue in term.Values) { // try to find filter by value var foundFilter = filtersWithValues.FirstOrDefault(x => x.Values.Any(y => y.Id.Equals(termValue))); if (foundFilter != null) { filter = foundFilter.Filter; var appliedFilter = BrowseFilterHelper.Convert(filter, term.Values); criteria.Apply(appliedFilter); } } } else if (filter != null) // predefined filter { var attributeFilter = filter as AttributeFilter; if (attributeFilter != null && attributeFilter.Values == null) { filter = new AttributeFilter { Key = attributeFilter.Key, Values = BrowseFilterHelper.CreateAttributeFilterValues(term.Values), IsLocalized = attributeFilter.IsLocalized, DisplayNames = attributeFilter.DisplayNames, }; } var appliedFilter = BrowseFilterHelper.Convert(filter, term.Values); criteria.Apply(appliedFilter); } else // custom term { if (!term.Key.StartsWith("_")) // ignore system terms, we can't filter by them { var attr = new AttributeFilter { Key = term.Key, Values = BrowseFilterHelper.CreateAttributeFilterValues(term.Values) }; criteria.Apply(attr); } } } } #endregion #region Sorting var categoryId = Outline.AsCategoryId(); var sorts = Sort.AsSortInfoes(); var sortFields = new List <SearchSortField>(); var priorityFieldName = string.Format(CultureInfo.InvariantCulture, "priority_{0}_{1}", catalog, categoryId).ToLower(); if (!sorts.IsNullOrEmpty()) { foreach (var sortInfo in sorts) { var fieldName = sortInfo.SortColumn.ToLowerInvariant(); var isDescending = sortInfo.SortDirection == SortDirection.Descending; switch (fieldName) { case "price": if (criteria.Pricelists != null) { sortFields.AddRange( criteria.Pricelists.Select( priceList => new SearchSortField(string.Format(CultureInfo.InvariantCulture, "price_{0}_{1}", criteria.Currency.ToLower(), priceList.ToLower())) { IgnoredUnmapped = true, IsDescending = isDescending, DataType = SearchSortField.DOUBLE }) .ToArray()); } break; case "priority": sortFields.Add(new SearchSortField(priorityFieldName, isDescending) { IgnoredUnmapped = true }); sortFields.Add(new SearchSortField("priority", isDescending)); break; case "name": case "title": sortFields.Add(new SearchSortField("name", isDescending)); break; default: sortFields.Add(new SearchSortField(fieldName, isDescending)); break; } } } if (!sortFields.Any()) { sortFields.Add(new SearchSortField(priorityFieldName, true) { IgnoredUnmapped = true }); sortFields.Add(new SearchSortField("priority", true)); sortFields.AddRange(CatalogItemSearchCriteria.DefaultSortOrder.GetSort()); } criteria.Sort = new SearchSort(sortFields.ToArray()); #endregion return(criteria); }