Full text profile search for the member directory
This commit is contained in:
parent
6ac121b345
commit
616f6ae76b
|
@ -68,6 +68,11 @@ var (
|
|||
"music_movies",
|
||||
"hide_age",
|
||||
}
|
||||
EssayProfileFields = []string{
|
||||
"about_me",
|
||||
"interests",
|
||||
"music_movies",
|
||||
}
|
||||
|
||||
// Site preference names (stored in ProfileField table)
|
||||
SitePreferenceFields = []string{
|
||||
|
|
|
@ -32,7 +32,8 @@ func Search() http.HandlerFunc {
|
|||
// Search filters.
|
||||
var (
|
||||
isCertified = r.FormValue("certified")
|
||||
username = r.FormValue("name") // username search
|
||||
username = r.FormValue("name") // username search
|
||||
searchTerm = r.FormValue("search") // profile text search
|
||||
gender = r.FormValue("gender")
|
||||
orientation = r.FormValue("orientation")
|
||||
maritalStatus = r.FormValue("marital_status")
|
||||
|
@ -48,6 +49,8 @@ func Search() http.HandlerFunc {
|
|||
ageMin, ageMax = ageMax, ageMin
|
||||
}
|
||||
|
||||
search := models.ParseSearchString(searchTerm)
|
||||
|
||||
// Get current user.
|
||||
currentUser, err := session.CurrentUser(r)
|
||||
if err != nil {
|
||||
|
@ -91,6 +94,7 @@ func Search() http.HandlerFunc {
|
|||
Orientation: orientation,
|
||||
MaritalStatus: maritalStatus,
|
||||
HereFor: hereFor,
|
||||
ProfileText: search,
|
||||
Certified: isCertified == "true",
|
||||
NotCertified: isCertified == "false",
|
||||
InnerCircle: isCertified == "circle",
|
||||
|
@ -127,6 +131,7 @@ func Search() http.HandlerFunc {
|
|||
"MaritalStatus": maritalStatus,
|
||||
"HereFor": hereFor,
|
||||
"EmailOrUsername": username,
|
||||
"Search": searchTerm,
|
||||
"AgeMin": ageMin,
|
||||
"AgeMax": ageMax,
|
||||
"FriendSearch": friendSearch,
|
||||
|
|
|
@ -258,6 +258,7 @@ type UserSearch struct {
|
|||
Orientation string
|
||||
MaritalStatus string
|
||||
HereFor string
|
||||
ProfileText *Search
|
||||
Certified bool
|
||||
NotCertified bool
|
||||
InnerCircle bool
|
||||
|
@ -364,6 +365,30 @@ func SearchUsers(user *User, search *UserSearch, pager *Pagination) ([]*User, er
|
|||
placeholders = append(placeholders, "here_for", "%"+search.HereFor+"%")
|
||||
}
|
||||
|
||||
// Profile text search.
|
||||
if terms := search.ProfileText; terms != nil {
|
||||
for _, term := range terms.Includes {
|
||||
var ilike = "%" + strings.ToLower(term) + "%"
|
||||
wheres = append(wheres, `
|
||||
EXISTS (
|
||||
SELECT 1 FROM profile_fields
|
||||
WHERE user_id = users.id AND name IN ? AND value ILIKE ?
|
||||
)
|
||||
`)
|
||||
placeholders = append(placeholders, config.EssayProfileFields, ilike)
|
||||
}
|
||||
for _, term := range terms.Excludes {
|
||||
var ilike = "%" + strings.ToLower(term) + "%"
|
||||
wheres = append(wheres, `
|
||||
NOT EXISTS (
|
||||
SELECT 1 FROM profile_fields
|
||||
WHERE user_id = users.id AND name IN ? AND value ILIKE ?
|
||||
)
|
||||
`)
|
||||
placeholders = append(placeholders, config.EssayProfileFields, ilike)
|
||||
}
|
||||
}
|
||||
|
||||
// Only admin user can show disabled/banned users.
|
||||
var statuses = []string{}
|
||||
if user.HasAdminScope(config.ScopeUserBan) {
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"code.nonshy.com/nonshy/website/pkg/config"
|
||||
"code.nonshy.com/nonshy/website/pkg/log"
|
||||
)
|
||||
|
||||
|
@ -55,7 +56,7 @@ func CountNotesAboutUser(currentUser *User, user *User) int64 {
|
|||
count int64
|
||||
)
|
||||
|
||||
if currentUser.IsAdmin {
|
||||
if currentUser.HasAdminScope(config.ScopeUserNotes) {
|
||||
wheres = append(wheres, "about_user_id = ?")
|
||||
placeholders = append(placeholders, user.ID)
|
||||
} else {
|
||||
|
|
|
@ -87,9 +87,9 @@
|
|||
|
||||
<div class="column pr-1">
|
||||
<div class="field">
|
||||
<label class="label">Status:</label>
|
||||
<label class="label" for="certified">Status:</label>
|
||||
<div class="select is-fullwidth">
|
||||
<select id="certified" name="certified">
|
||||
<select id="certified" name="certified" id="certified">
|
||||
<optgroup label="Certification Status">
|
||||
<option value="true">Only certified users</option>
|
||||
<option value="false"{{if eq $Root.Certified "false"}} selected{{end}}>Non-certified only</option>
|
||||
|
@ -115,15 +115,33 @@
|
|||
|
||||
<div class="column px-1">
|
||||
<div class="field">
|
||||
<label class="label">Name or username:</label>
|
||||
<label class="label" for="name">Name or username:</label>
|
||||
<input type="text" class="input"
|
||||
name="name"
|
||||
name="name" id="name"
|
||||
autocomplete="off"
|
||||
value="{{$Root.EmailOrUsername}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column px-1">
|
||||
<div class="column is-half pl-1">
|
||||
<div class="field">
|
||||
<label class="label" for="search">Profile text:</label>
|
||||
<input type="text" class="input"
|
||||
name="search" id="search"
|
||||
autocomplete="off"
|
||||
value="{{$Root.Search}}">
|
||||
<p class="help">
|
||||
Tip: you can <span class="has-text-success">"quote exact phrases"</span> and
|
||||
<span class="has-text-success">-exclude</span> words (or
|
||||
<span class="has-text-success">-"exclude phrases"</span>) from your search.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="columns is-centered">
|
||||
|
||||
<div class="column pr-1">
|
||||
<div class="field">
|
||||
<label class="label">Age:</label>
|
||||
<div class="columns is-mobile is-gapless">
|
||||
|
@ -151,7 +169,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column pl-1">
|
||||
<div class="column px-1">
|
||||
<div class="field">
|
||||
<label class="label" for="gender">Gender:</label>
|
||||
<div class="select is-fullwidth">
|
||||
|
@ -165,10 +183,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="columns is-centered">
|
||||
|
||||
<div class="column pr-1">
|
||||
<div class="column px-1">
|
||||
<div class="field">
|
||||
<label class="label" for="orientation">Orientation:</label>
|
||||
<div class="select is-fullwidth">
|
||||
|
@ -182,7 +197,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column px-1">
|
||||
<div class="column pl-1">
|
||||
<div class="field">
|
||||
<label class="label" for="marital_status">Relationship:</label>
|
||||
<div class="select is-fullwidth">
|
||||
|
@ -196,7 +211,10 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column px-1">
|
||||
</div>
|
||||
<div class="columns is-centered">
|
||||
|
||||
<div class="column pr-1">
|
||||
<div class="field">
|
||||
<label class="label" for="here_for">Here for:</label>
|
||||
<div class="select is-fullwidth">
|
||||
|
|
Loading…
Reference in New Issue
Block a user