Skip to content

Commit b6083af

Browse files
committed
Search: More on forum common facets
1 parent ac97288 commit b6083af

16 files changed

Lines changed: 597 additions & 173 deletions

src/Libraries/SmartStore.Core/Search/Facets/FacetDescriptor.cs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,34 +29,6 @@ public FacetDescriptor(string key)
2929
Key = key;
3030
}
3131

32-
/// <summary>
33-
/// Gets the string resource key for a facet group kind
34-
/// </summary>
35-
/// <param name="kind">Facet group kind</param>
36-
/// <returns>Resource key</returns>
37-
public static string GetLabelResourceKey(FacetGroupKind kind)
38-
{
39-
switch (kind)
40-
{
41-
case FacetGroupKind.Category:
42-
return "Search.Facet.Category";
43-
case FacetGroupKind.Brand:
44-
return "Search.Facet.Manufacturer";
45-
case FacetGroupKind.Price:
46-
return "Search.Facet.Price";
47-
case FacetGroupKind.Rating:
48-
return "Search.Facet.Rating";
49-
case FacetGroupKind.DeliveryTime:
50-
return "Search.Facet.DeliveryTime";
51-
case FacetGroupKind.Availability:
52-
return "Search.Facet.Availability";
53-
case FacetGroupKind.NewArrivals:
54-
return "Search.Facet.NewArrivals";
55-
default:
56-
return null;
57-
}
58-
}
59-
6032
/// <summary>
6133
/// Gets the key / field name.
6234
/// </summary>

src/Libraries/SmartStore.Services/Search/Catalog/Modelling/CatalogSearchQueryAliasMapper.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
using SmartStore.Services.Catalog;
1111
using SmartStore.Services.Configuration;
1212
using SmartStore.Services.Localization;
13+
using SmartStore.Services.Search.Extensions;
1314

1415
namespace SmartStore.Services.Search.Modelling
1516
{
16-
public class CatalogSearchQueryAliasMapper : ICatalogSearchQueryAliasMapper
17+
public class CatalogSearchQueryAliasMapper : ICatalogSearchQueryAliasMapper
1718
{
1819
private const string ALL_ATTRIBUTE_ID_BY_ALIAS_KEY = "search.attribute.id.alias.mappings.all";
1920
private const string ALL_ATTRIBUTE_ALIAS_BY_ID_KEY = "search.attribute.alias.id.mappings.all";
@@ -66,11 +67,6 @@ protected string CreateOptionKey(string prefix, int languageId, int optionId)
6667
return $"{prefix}.{languageId}.{optionId}";
6768
}
6869

69-
protected string CreateSettingKey(FacetGroupKind kind, int languageId)
70-
{
71-
return $"FacetGroupKind-{kind.ToString()}-Alias-{languageId}";
72-
}
73-
7470
protected void CachedLocalizedAlias(string localeKeyGroup, Action<LocalizedProperty> caching)
7571
{
7672
_localizedPropertyRepository.TableUntracked
@@ -464,7 +460,7 @@ protected virtual IDictionary<string, string> GetCommonFacetAliasByGroupKindMapp
464460
{
465461
foreach (var groupKind in groupKinds)
466462
{
467-
var key = CreateSettingKey(groupKind, language.Id);
463+
var key = FacetUtility.GetFacetAliasSettingKey(groupKind, language.Id);
468464
var value = _settingService.GetSettingByKey<string>(key);
469465
if (value.HasValue())
470466
{
@@ -486,7 +482,7 @@ public string GetCommonFacetAliasByGroupKind(FacetGroupKind kind, int languageId
486482
{
487483
var mappings = GetCommonFacetAliasByGroupKindMappings();
488484

489-
return mappings.Get(CreateSettingKey(kind, languageId));
485+
return mappings.Get(FacetUtility.GetFacetAliasSettingKey(kind, languageId));
490486
}
491487

492488
#endregion

src/Libraries/SmartStore.Services/Search/Catalog/Modelling/CatalogSearchQueryFactory.cs

Lines changed: 12 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using SmartStore.Services.Catalog;
1212
using SmartStore.Utilities;
1313
using SmartStore.Services.Security;
14+
using SmartStore.Services.Search.Extensions;
1415

1516
namespace SmartStore.Services.Search.Modelling
1617
{
@@ -35,14 +36,12 @@ namespace SmartStore.Services.Search.Modelling
3536

3637
public class CatalogSearchQueryFactory : SearchQueryFactoryBase, ICatalogSearchQueryFactory
3738
{
38-
protected static readonly string[] _tokens = new string[] { "q", "i", "s", "o", "p", "c", "m", "r", "a", "n", "d", "v" };
3939
protected static readonly string[] _instantSearchFields = new string[] { "manufacturer", "sku", "gtin", "mpn", "attrname", "variantname" };
4040

4141
protected readonly CatalogSettings _catalogSettings;
4242
protected readonly SearchSettings _searchSettings;
4343
protected readonly ICommonServices _services;
4444
protected readonly ICatalogSearchQueryAliasMapper _catalogSearchQueryAliasMapper;
45-
private Multimap<string, string> _aliases;
4645

4746
public CatalogSearchQueryFactory(
4847
HttpContextBase httpContext,
@@ -64,7 +63,9 @@ public CatalogSearchQueryFactory(
6463

6564
public CatalogSearchQuery Current { get; private set; }
6665

67-
public CatalogSearchQuery CreateFromQuery()
66+
protected override string[] Tokens => new string[] { "q", "i", "s", "o", "p", "c", "m", "r", "a", "n", "d", "v" };
67+
68+
public CatalogSearchQuery CreateFromQuery()
6869
{
6970
var ctx = _httpContext;
7071

@@ -88,7 +89,9 @@ public CatalogSearchQuery CreateFromQuery()
8889
foreach (var fieldName in _instantSearchFields)
8990
{
9091
if (_searchSettings.SearchFields.Contains(fieldName))
92+
{
9193
fields.Add(fieldName);
94+
}
9295
}
9396
}
9497
else
@@ -103,19 +106,19 @@ public CatalogSearchQuery CreateFromQuery()
103106
.VisibleIndividuallyOnly(true)
104107
.BuildFacetMap(!isInstantSearch);
105108

106-
// Visibility
109+
// Visibility.
107110
query.VisibleOnly(!QuerySettings.IgnoreAcl ? _services.WorkContext.CurrentCustomer : null);
108111

109-
// Store
112+
// Store.
110113
if (!QuerySettings.IgnoreMultiStore)
111114
{
112115
query.HasStoreId(_services.StoreContext.CurrentStore.Id);
113116
}
114117

115-
// Availability
118+
// Availability.
116119
ConvertAvailability(query, routeData, origin);
117120

118-
// Instant-Search never uses these filter parameters
121+
// Instant-Search never uses these filter parameters.
119122
if (!isInstantSearch)
120123
{
121124
ConvertPagingSorting(query, routeData, origin);
@@ -143,14 +146,7 @@ protected virtual void ConvertPagingSorting(CatalogSearchQuery query, RouteData
143146
var orderBy = GetValueFor<ProductSortingEnum?>("o");
144147
if (orderBy == null || orderBy == ProductSortingEnum.Initial)
145148
{
146-
if(origin.Equals("Search/Search"))
147-
{
148-
orderBy = _searchSettings.DefaultSortOrder;
149-
}
150-
else
151-
{
152-
orderBy = _catalogSettings.DefaultSortOrder;
153-
}
149+
orderBy = origin.IsCaseInsensitiveEqual("Search/Search") ? _searchSettings.DefaultSortOrder : _catalogSettings.DefaultSortOrder;
154150
}
155151

156152
query.CustomData["CurrentSortOrder"] = orderBy.Value;
@@ -337,7 +333,7 @@ private void AddFacet(
337333
}
338334

339335
var descriptor = new FacetDescriptor(fieldName);
340-
descriptor.Label = _services.Localization.GetResource(FacetDescriptor.GetLabelResourceKey(kind) ?? kind.ToString());
336+
descriptor.Label = _services.Localization.GetResource(FacetUtility.GetLabelResourceKey(kind) ?? kind.ToString());
341337
descriptor.IsMultiSelect = isMultiSelect;
342338
descriptor.DisplayOrder = displayOrder;
343339
descriptor.OrderBy = sorting;
@@ -480,27 +476,6 @@ protected virtual void ConvertPrice(CatalogSearchQuery query, RouteData routeDat
480476
});
481477
}
482478

483-
protected virtual bool TryParseRange(string query, out double? min, out double? max)
484-
{
485-
min = max = null;
486-
487-
if (query.IsEmpty())
488-
{
489-
return false;
490-
}
491-
492-
// Format: from~to || from[~] || ~to
493-
var arr = query.Split('~').Select(x => x.Trim()).Take(2).ToArray();
494-
495-
CommonHelper.TryConvert(arr[0], out min);
496-
if (arr.Length == 2)
497-
{
498-
CommonHelper.TryConvert(arr[1], out max);
499-
}
500-
501-
return min != null || max != null;
502-
}
503-
504479
protected virtual void ConvertRating(CatalogSearchQuery query, RouteData routeData, string origin)
505480
{
506481
double? fromRate;
@@ -622,46 +597,5 @@ protected virtual bool GetValueFor<T>(CatalogSearchQuery query, string key, Face
622597
{
623598
return GetValueFor(_catalogSearchQueryAliasMapper.GetCommonFacetAliasByGroupKind(kind, query.LanguageId ?? 0) ?? key, out value);
624599
}
625-
626-
protected virtual Multimap<string, string> Aliases
627-
{
628-
get
629-
{
630-
if (_aliases == null)
631-
{
632-
_aliases = new Multimap<string, string>();
633-
634-
if (_httpContext.Request != null)
635-
{
636-
var form = _httpContext.Request.Form;
637-
var query = _httpContext.Request.QueryString;
638-
639-
if (form != null)
640-
{
641-
foreach (var key in form.AllKeys)
642-
{
643-
if (key.HasValue() && !_tokens.Contains(key))
644-
{
645-
_aliases.AddRange(key, form[key].SplitSafe(","));
646-
}
647-
}
648-
}
649-
650-
if (query != null)
651-
{
652-
foreach (var key in query.AllKeys)
653-
{
654-
if (key.HasValue() && !_tokens.Contains(key))
655-
{
656-
_aliases.AddRange(key, query[key].SplitSafe(","));
657-
}
658-
}
659-
}
660-
}
661-
}
662-
663-
return _aliases;
664-
}
665-
}
666600
}
667601
}

src/Libraries/SmartStore.Services/Search/Catalog/Modelling/CatalogSearchQueryModelBinder.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
using System;
2-
using System.Web.Mvc;
1+
using System.Web.Mvc;
32
using Autofac.Integration.Mvc;
43

54
namespace SmartStore.Services.Search.Modelling
65
{
7-
[ModelBinderType(typeof(CatalogSearchQuery))]
6+
[ModelBinderType(typeof(CatalogSearchQuery))]
87
public class CatalogSearchQueryModelBinder : IModelBinder
98
{
109
private readonly ICatalogSearchQueryFactory _factory;
@@ -18,7 +17,7 @@ public object BindModel(ControllerContext controllerContext, ModelBindingContext
1817
{
1918
if (_factory.Current != null)
2019
{
21-
// Dont' bind again for current request
20+
// Don't bind again for current request.
2221
return _factory.Current;
2322
}
2423

@@ -31,16 +30,13 @@ public object BindModel(ControllerContext controllerContext, ModelBindingContext
3130
}
3231

3332
var modelType = bindingContext.ModelType;
34-
3533
if (modelType != typeof(CatalogSearchQuery))
3634
{
3735
return new CatalogSearchQuery();
3836
}
3937

4038
var query = _factory.CreateFromQuery();
41-
4239
return query;
43-
4440
}
4541
}
4642
}

src/Libraries/SmartStore.Services/Search/Extensions/FacetUtility.cs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,14 @@ public static string GetPublicName(Customer customer, bool userNamesEnabled)
170170
{
171171
name = GetPublicName(customer.FirstName, customer.LastName);
172172
}
173+
else
174+
{
175+
var atSymbol = name.IndexOf('@');
176+
if (atSymbol > 1)
177+
{
178+
name = name.Substring(0, atSymbol);
179+
}
180+
}
173181

174182
if (customer.BillingAddress != null && string.IsNullOrWhiteSpace(name))
175183
{
@@ -182,7 +190,8 @@ public static string GetPublicName(Customer customer, bool userNamesEnabled)
182190
public static IQueryable<Customer> GetCustomersByNumberOfPosts(
183191
IRepository<ForumPost> forumPostRepository,
184192
IRepository<StoreMapping> storeMappingRepository,
185-
int storeId)
193+
int storeId,
194+
int minHitCount = 1)
186195
{
187196
var postQuery = forumPostRepository.TableUntracked
188197
.Expand(x => x.Customer)
@@ -207,12 +216,60 @@ group p by p.CustomerId into grp
207216
grp.FirstOrDefault().Customer // Cannot be null.
208217
};
209218

219+
groupQuery = minHitCount > 1
220+
? groupQuery.Where(x => x.Count >= minHitCount)
221+
: groupQuery;
222+
210223
var query = groupQuery
211224
.OrderByDescending(x => x.Count)
212225
.Select(x => x.Customer)
213226
.Where(x => x.CustomerRoles.FirstOrDefault(y => y.SystemName == SystemCustomerRoleNames.Guests) == null && !x.Deleted && x.Active && !x.IsSystemAccount);
214227

215228
return query;
216229
}
230+
231+
/// <summary>
232+
/// Gets the string resource key for a facet group kind
233+
/// </summary>
234+
/// <param name="kind">Facet group kind</param>
235+
/// <returns>Resource key</returns>
236+
public static string GetLabelResourceKey(FacetGroupKind kind)
237+
{
238+
switch (kind)
239+
{
240+
case FacetGroupKind.Category:
241+
return "Search.Facet.Category";
242+
case FacetGroupKind.Brand:
243+
return "Search.Facet.Manufacturer";
244+
case FacetGroupKind.Price:
245+
return "Search.Facet.Price";
246+
case FacetGroupKind.Rating:
247+
return "Search.Facet.Rating";
248+
case FacetGroupKind.DeliveryTime:
249+
return "Search.Facet.DeliveryTime";
250+
case FacetGroupKind.Availability:
251+
return "Search.Facet.Availability";
252+
case FacetGroupKind.NewArrivals:
253+
return "Search.Facet.NewArrivals";
254+
case FacetGroupKind.Forum:
255+
return "Search.Facet.Forum";
256+
case FacetGroupKind.Customer:
257+
return "Search.Facet.Customer";
258+
case FacetGroupKind.Date:
259+
return "Search.Facet.Date";
260+
default:
261+
return null;
262+
}
263+
}
264+
265+
public static string GetFacetAliasSettingKey(FacetGroupKind kind, int languageId, string scope = null)
266+
{
267+
if (scope.HasValue())
268+
{
269+
return $"FacetGroupKind-{kind.ToString()}-Alias-{languageId}-{scope}";
270+
}
271+
272+
return $"FacetGroupKind-{kind.ToString()}-Alias-{languageId}";
273+
}
217274
}
218275
}

0 commit comments

Comments
 (0)