summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMrYummy <elemental428@gmail.com>2017-05-28 18:08:57 -0400
committerMrYummy <elemental428@gmail.com>2017-06-18 13:11:36 -0400
commit1316d7ca0335dd4ff5f8b4c7bb46e961b37503f0 (patch)
tree50259904cb3614f3161ef8a5c152017ef597a13d
parente7463524af03a62b8ba4adbdee29efe5f547c2d4 (diff)
Added Searching Features
* Added Thread Search Feature * Added User Search Feature * Re-organized searching, added @mention support to author search
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/controllers/blogposts_controller.rb2
-rw-r--r--app/controllers/forums_controller.rb2
-rw-r--r--app/controllers/forumthreads_controller.rb23
-rw-r--r--app/controllers/users_controller.rb13
-rw-r--r--app/helpers/mailer_helper.rb2
-rw-r--r--app/helpers/users_helper.rb2
-rw-r--r--app/models/forum.rb2
-rw-r--r--app/models/forumthread.rb43
-rw-r--r--app/models/role.rb2
-rw-r--r--app/models/user.rb4
-rw-r--r--app/views/application/_md_editor_user.html.erb8
-rw-r--r--app/views/forums/index.html.erb4
-rw-r--r--app/views/forums/show.html.erb13
-rw-r--r--app/views/forumthreads/index.html.erb84
-rw-r--r--app/views/forumthreads/search.html.erb56
-rw-r--r--app/views/users/index.html.erb31
-rw-r--r--config/routes.rb7
-rw-r--r--db/migrate/20170522210610_add_search_indexes.rb8
-rw-r--r--db/schema.rb12
20 files changed, 293 insertions, 27 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index a0e166e..d489611 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -75,4 +75,4 @@ class ApplicationController < ActionController::Base
!!(current_user && current_user.confirmed?)
end
-end \ No newline at end of file
+end
diff --git a/app/controllers/blogposts_controller.rb b/app/controllers/blogposts_controller.rb
index 79c9e5d..7a9851d 100644
--- a/app/controllers/blogposts_controller.rb
+++ b/app/controllers/blogposts_controller.rb
@@ -75,4 +75,4 @@ class BlogpostsController < ApplicationController
end
end
-end \ No newline at end of file
+end
diff --git a/app/controllers/forums_controller.rb b/app/controllers/forums_controller.rb
index 486d21c..761a86b 100644
--- a/app/controllers/forums_controller.rb
+++ b/app/controllers/forums_controller.rb
@@ -1,4 +1,5 @@
class ForumsController < ApplicationController
+
before_filter :check_permission, only: [:show, :edit, :update, :destroy]
def index
@@ -77,7 +78,6 @@ class ForumsController < ApplicationController
redirect_to forums_path
end
-
private
def check_permission
diff --git a/app/controllers/forumthreads_controller.rb b/app/controllers/forumthreads_controller.rb
index b1dffd9..e21c6d4 100644
--- a/app/controllers/forumthreads_controller.rb
+++ b/app/controllers/forumthreads_controller.rb
@@ -3,9 +3,14 @@ class ForumthreadsController < ApplicationController
before_filter :check_permission, only: [:show, :edit, :update, :destroy]
def index
- redirect_to forum_path(@thread.forum.forumgroup, f)
+ if params[:label] && !Label.where("lower(name) = ?", params[:label].downcase).try(:first) && params[:label].downcase != "no label"
+ flash[:alert] = "'#{params[:label]}' is not a valid label."
+ redirect_to forumthreads_path(params.except(:label, :controller, :action))
+ return
+ end
+ @threads = Forumthread.filter(current_user, params[:title], params[:content], params[:reply], params[:label], User.where("lower(ign) = ?", params[:author].to_s.downcase).try(:first), params[:query], Forum.where(id: params[:id]).try(:first))
+ .page(params[:page]).per(30)
end
-
def show
if params[:reverse]
@replies = @thread.replies.reverse_order.page(params[:page])
@@ -80,6 +85,20 @@ class ForumthreadsController < ApplicationController
redirect_to @thread.forum
end
+ def search
+ end
+
+ def search_redirect
+ params.each do |key, value|
+ params[key] = nil if params[key] == ""
+ end
+ params[:id] = nil if params[:id] == "Search All Threads"
+ params[:label] = nil if params[:label] && params[:label].downcase == "label"
+ params[:author] = params[:author].tr("@ ", "") if params[:author]
+ params_list = Hash[params.except(:commit, :utf8, :authenticity_token)]
+ redirect_to forumthreads_path(params_list)
+ end
+
private
def check_permission
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 16f42d3..6b31d22 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -4,7 +4,7 @@ class UsersController < ApplicationController
include MailerHelper
include ERB::Util
- before_filter :set_user, except: [:index, :new, :create, :lost_password, :reset_password, :suggestions]
+ before_filter :set_user, except: [:index, :new, :create, :lost_password, :reset_password, :suggestions, :search_redirect]
def index
if params[:role]
@@ -13,7 +13,7 @@ class UsersController < ApplicationController
else
if role = Role.get(params[:role])
@users = User.joins(:role).where(role: role)
- else
+ elsif params[:search] == nil
flash[:alert] = "role '#{params[:role]}' does not exist!"
redirect_to users_path
return
@@ -30,6 +30,7 @@ class UsersController < ApplicationController
else
@users = User.joins(:role).where.not(id: User.first.id) #Remove first user
end
+ @users = User.search(@users, params[:search]) if params[:search]
@users = @users.order("roles.value desc", "confirmed desc", :name) unless params[:badge]
@count = @users.size
@users = @users.page(params[:page]).per(100)
@@ -339,6 +340,14 @@ class UsersController < ApplicationController
end
end
+ def search_redirect
+ params.each do |key, value|
+ params[key] = nil if params[key] == ""
+ end
+ params_list = Hash[params.except(:commit, :utf8, :authenticity_token)]
+ redirect_to users_path(params_list)
+ end
+
private
def validate_token(uuid, email, token)
diff --git a/app/helpers/mailer_helper.rb b/app/helpers/mailer_helper.rb
index dbacf81..5e5649c 100644
--- a/app/helpers/mailer_helper.rb
+++ b/app/helpers/mailer_helper.rb
@@ -24,4 +24,4 @@ module MailerHelper
end
end
end
-end \ No newline at end of file
+end
diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
index 2ce1765..7ad99d8 100644
--- a/app/helpers/users_helper.rb
+++ b/app/helpers/users_helper.rb
@@ -52,4 +52,4 @@ module UsersHelper
end
end
-end \ No newline at end of file
+end
diff --git a/app/models/forum.rb b/app/models/forum.rb
index 39e8f2a..a239dbc 100644
--- a/app/models/forum.rb
+++ b/app/models/forum.rb
@@ -32,4 +32,4 @@ class Forum < ActiveRecord::Base
def to_param
[id, to_s.parameterize].join("-")
end
-end \ No newline at end of file
+end
diff --git a/app/models/forumthread.rb b/app/models/forumthread.rb
index 905e4d3..86823ac 100644
--- a/app/models/forumthread.rb
+++ b/app/models/forumthread.rb
@@ -65,4 +65,47 @@ class Forumthread < ActiveRecord::Base
def to_param
[id, to_s.parameterize].join("-")
end
+
+ def self.filter (user, title, content, reply, label, author, query, forum)
+ userid = user.try(:id).to_i
+ role = user.try(:role).to_i
+
+ can_read = "COALESCE(forum_role_read.value, 0) <= ? AND COALESCE(forumgroup_role_read.value, 0) <= ?"
+ sticky_can_write = "sticky = true AND (COALESCE(forum_role_write.value, 0) <= ? OR COALESCE(forumgroup_role_write.value, 0) <= ?)"
+
+ threads = forum.try(:forumthreads) || Forumthread
+ threads = threads.where("forumthreads.user_author_id = ? OR (#{can_read}) OR (#{sticky_can_write})", userid, role, role, role, role)
+ .joins("LEFT JOIN threadreplies ON forumthreads.id = threadreplies.forumthread_id")
+ .joins(forum: :forumgroup)
+ .joins("LEFT JOIN roles as forum_role_read ON forums.role_read_id = forum_role_read.id")
+ .joins("LEFT JOIN roles as forum_role_write ON forums.role_write_id = forum_role_write.id")
+ .joins("LEFT JOIN roles as forumgroup_role_read ON forumgroups.role_read_id = forumgroup_role_read.id")
+ .joins("LEFT JOIN roles as forumgroup_role_write ON forumgroups.role_write_id = forumgroup_role_write.id")
+
+ if [content, title, reply, label, author, query].any?
+ label_o = Label.find_by(name: label)
+ if label_o
+ threads = threads.where(label: label_o)
+ elsif label.try(:downcase) == "no label"
+ threads = threads.where(label: nil)
+ end
+
+ threads = threads.where(user_author: author) if author
+
+ if query
+ threads = threads.where("MATCH (title, forumthreads.content) AGAINST (?) OR MATCH (threadreplies.content) AGAINST (?)", query, query)
+ elsif [title, content, reply].any?
+ query = [title, content, reply].select(&:present?).join(" ")
+ threads = threads.where("MATCH (title) AGAINST (?)", title) if title
+ threads = threads.where("MATCH (forumthreads.content) AGAINST (?)", content) if content
+ threads = threads.where("MATCH (threadreplies.content) AGAINST (?)", reply) if reply
+ threads = threads.group("threadreplies.id", "forumthreads.id")
+ threads = threads.order("(MATCH (title, forumthreads.content) AGAINST ('#{query}')) DESC")
+ end
+ end
+
+ threads = threads.order("sticky desc", "threadreplies.created_at desc", "forumthreads.created_at desc") if threads.order_values.empty?
+
+ threads
+ end
end
diff --git a/app/models/role.rb b/app/models/role.rb
index 708fb40..e780b8c 100644
--- a/app/models/role.rb
+++ b/app/models/role.rb
@@ -53,4 +53,4 @@ class Role < ActiveRecord::Base
Role.order(:value).select {|r| r >= from}.select {|r| r <= to}
end
-end \ No newline at end of file
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index ab7471e..a96410a 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -174,4 +174,8 @@ class User < ActiveRecord::Base
def set_email_token
self.email_token ||= SecureRandom.hex(16)
end
+
+ def self.search (users, search)
+ return users.where("users.name like ? OR ign like ?", "%#{User.send(:sanitize_sql_like, search)}%", "%#{User.send(:sanitize_sql_like, search)}%")
+ end
end
diff --git a/app/views/application/_md_editor_user.html.erb b/app/views/application/_md_editor_user.html.erb
new file mode 100644
index 0000000..25f63a4
--- /dev/null
+++ b/app/views/application/_md_editor_user.html.erb
@@ -0,0 +1,8 @@
+<div class="md_editor">
+ <div class="field_container_user">
+ <% options = (defined?(options) && options || {}) %>
+ <% options[:class] = "#{options[:class]} editor_field" %>
+ <% options[:placeholder] ||= "Enter user's name. Prefix with \"@\" to get suggestions." %>
+ <%= text_field_tag name, content, options %>
+ </div>
+</div>
diff --git a/app/views/forums/index.html.erb b/app/views/forums/index.html.erb
index f09ea20..0a2fbaf 100644
--- a/app/views/forums/index.html.erb
+++ b/app/views/forums/index.html.erb
@@ -1,5 +1,7 @@
<% title "Forums" %>
+<%= link_to "All threads", forumthreads_path(params.except("controller", "action")), class: "btn blue right" %>
+
<div id="forum_groups">
<% @groups.each do |group| %>
<div class="item-group" id="group-<%= group.id %>">
@@ -56,4 +58,4 @@
<%= link_to "New group", new_forumgroup_path, class: "btn blue" %>
<% elsif mod? %>
<%= link_to "New group", "#", class: "btn blue", disabled: true %>
-<% end %> \ No newline at end of file
+<% end %>
diff --git a/app/views/forums/show.html.erb b/app/views/forums/show.html.erb
index 60f3185..9dcdad8 100644
--- a/app/views/forums/show.html.erb
+++ b/app/views/forums/show.html.erb
@@ -1,8 +1,15 @@
<%= link_to @forum.group, forumgroup_path(@forum.group) %> → <%= @forum %>
-<h1><%= title @forum %></h1>
+<h1>
+ <%= title @forum %>
+ <% params[:id] = params[:id].split("-")[0] %>
+ <%= link_to "Search Threads", forumthreads_path(params.except("action", "controller")), class: "btn blue right" %>
+</h1>
<% if @forum.can_write?(current_user) %>
- <p><%= link_to "New thread", new_forumthread_path(forum: @forum), class: "btn blue" %></p>
+ <p>
+ <%= link_to "New thread", new_forumthread_path(forum: @forum), class: "btn blue" %>
+ <% params[:id] = params[:id].split("-")[0] %>
+ </p>
<% end %>
<% if @forum.role_read && @forum.role_write && @forum.role_write < @forum.role_read %>
@@ -51,4 +58,4 @@
</div>
<% end %>
<%= paginate @threads %>
-</div> \ No newline at end of file
+</div>
diff --git a/app/views/forumthreads/index.html.erb b/app/views/forumthreads/index.html.erb
new file mode 100644
index 0000000..d765cda
--- /dev/null
+++ b/app/views/forumthreads/index.html.erb
@@ -0,0 +1,84 @@
+<%= link_to "Forums", forums_path %> →
+<% if params.to_hash.slice("label", "title", "content", "author", "reply").size > 0 %>
+ <%= link_to "All Threads", forumthreads_path %> → Search Results
+<% else %>
+ <%= "All Threads" %>
+<% end %>
+<% params_list = params.to_hash.slice("id", "query", "label", "title", "content", "author", "reply") %>
+<h1>
+ <% if params[:id] %>
+ <% text = "forum '#{Forum.find(params[:id]).name}'" %>
+ <% else %>
+ <% text = "all threads" %>
+ <% end %>
+ <% if params_list.size > 0 %>
+ <%= title "Search results in #{text} (#{@threads.length})" %>
+ <% else %>
+ <% if params[:id] %>
+ <%= title "All threads in #{text}" %>
+ <% else %>
+ <%= title "All Threads" %>
+ <% end %>
+ <% end %>
+ <br>
+ <%= link_to "Advanced Search", search_forumthreads_path(params_list), class: "btn right blue" %>
+ <% if params_list.size > 0 && params[:id] %>
+ <%= link_to "Show All Threads", forumthreads_path(params_list.except("id")), class: "btn right blue" %>
+ <% elsif params_list.size > 0 && !params[:id] %>
+ <%= link_to "Show All Threads", forumthreads_path, class: "btn right blue" %>
+ <% end %>
+ <% if params[:id] %>
+ <%= link_to "Go to Forum", forum_path(params[:id]), class: "btn right blue" %>
+ <% end %>
+</h1>
+<br>
+<%= form_tag({controller: "forumthreads", action: "search_redirect"}, method: :post, style: "margin:0px;height:40px") do %>
+ <%= text_field_tag "query", nil, placeholder: "Search...", style: "margin:0px;height:40px;width:300px" %>
+ <% params.each do |key, value| %>
+ <%= hidden_field_tag key, params[key] if params[key] && params[key] != params[:query] %>
+ <% end %>
+ <%= submit_tag "Go", class: "btn blue", style: "margin:0px;height:40px;width:40px" %>
+<% end %>
+</h1>
+<div id="forum_groups">
+ <% counter = 0 %>
+ <% @threads.each do |thread| %>
+ <% counter += 1 %>
+ <div class="item-group with-avatar" id="thread-<%= thread.id %>">
+ <div class="header">
+ <%= link_to(thread.author.avatar(64), thread.author, title: thread.author.ign) %>
+ <%= render partial: "users/username", locals: { user: thread.author } %>
+ <%= link_to thread do %>
+ <%= ago thread.created_at %>
+ <% end %>
+ <span class="comment-counter">
+ <%= link_to pluralize(thread.replies.count, "Reply"), thread %>
+ </span>
+ <div class="clear-right"></div>
+ </div>
+ <div class="items bold">
+ <div class="item <%= "#{"locked" if thread.locked}#{"sticky" if thread.sticky}" %>">
+ <%= render partial: "labels/label", locals: {label: thread.label} %><%= link_to truncate(thread.title, length: 60, omission: " …"), forumthread_path(thread), title: thread.title %>
+ <div class="item-info">
+ <% if rpl = thread.replies.last %>
+ <%= rpl.author.name %>
+ <%
+ position = thread.replies.count - 1
+ page = position / Kaminari.config.default_per_page + 1
+ %>
+ <%= link_to "replied", forumthread_path(thread, page: page) + "#reply-#{rpl.id}" %>
+ <%= ago rpl.created_at %>.
+ <% else %>
+ No replies yet.
+ <% end %>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </div>
+ </div>
+ <% end %>
+ <% if counter == 0 %>
+ <h3>No results found</h3>
+ <% end %>
+ <%= paginate @threads %>
+</div>
diff --git a/app/views/forumthreads/search.html.erb b/app/views/forumthreads/search.html.erb
new file mode 100644
index 0000000..a3c631f
--- /dev/null
+++ b/app/views/forumthreads/search.html.erb
@@ -0,0 +1,56 @@
+<% title "Thread Search" %>
+<h1>Thread Search</h1>
+<h3>Leave a field blank to ignore that search aspect.</h3>
+<% label = Label.where(name: params[:label]).first %>
+<table>
+ <tbody>
+<%= form_tag({controller: "forumthreads", action: "search_redirect"}, method: :post) do %>
+ <%
+ forums = []
+ Forum.all.sort_by{ |f| f.forumgroup && f.forumgroup.position || 0 }.each do |f|
+ if current_user != nil && current_user.role_id > f.role_read_id.to_i || current_user == nil && f.role_read_id == nil
+ forums << ["#{f.forumgroup.name} → #{f.name}", f.id] if f.forumgroup
+ end
+ end
+ %>
+ <% label_list = Label.pluck(:name).insert(0, "Label").insert(1, "No Label") %>
+ <tr>
+ <td>Forum</td>
+ <td><%= select_tag "id", options_for_select(["Search All Threads"] + forums, params[:id]) %></td>
+ </tr>
+ <tr>
+ <td>Label</td>
+ <td>
+ <%= select_tag "label", options_for_select(label_list, params[:label]), class: "auto-width" %>
+ </td>
+ </tr>
+ <tr>
+ <td>Title</td>
+ <td>
+ <%= text_field_tag "title", params[:title], placeholder: "Search Titles" %>
+ </td>
+ </tr>
+ <tr>
+ <td>Content</td>
+ <td>
+ <%= text_field_tag "content", params[:content], placeholder: "Search Contents" %>
+ </td>
+ <tr>
+ <td>Author</td>
+ <td>
+ <%= render partial: "md_editor_user", locals: {name: "author", content: params[:author]} %>
+ </td>
+ </tr>
+ <td>Replies</td>
+ <td>
+ <%= text_field_tag "reply", params[:reply], placeholder: "Search Replies" %>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <%= submit_tag "Go", class: "btn blue", style: "width:50px" %>
+ </td>
+ </tr>
+<% end %>
+ </tbody>
+</table>
diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb
index 95ab480..8df0fd0 100644
--- a/app/views/users/index.html.erb
+++ b/app/views/users/index.html.erb
@@ -1,14 +1,29 @@
+<%= form_tag({controller: "users", action: "search_redirect"}, method: :post, style: "margin:0px;height:40px") do %>
+ <%= text_field_tag "search", nil, placeholder: "Search for a user", style: "margin:0px;height:40px;width:300px" %>
+ <%= submit_tag "Go", class: "btn blue", style: "margin:0px;height:40px;width:40px" %>
+ <%= hidden_field_tag "role", params[:role] %>
+<% end %>
+
<h1>
- <% if params[:role] && !params[:badge]%>
- <%= title "All '#{params[:role]}' users" %>
- <% elsif params[:badge] && !params[:role] %>
- <%= title "All '#{params[:badge]}' users" %>
- <% elsif params[:role] && params[:badge] %>
- <%= title "All '#{params[:role]}' and '#{params[:badge]}' users" %>
+ <%
+ if params[:role] && !params[:badge]
+ text = "All '#{params[:role]}' users"
+ elsif params[:badge] && !params[:role]
+ text = "All '#{params[:badge]}' users"
+ elsif params[:role] && params[:badge]
+ text = "All '#{params[:role]}' and '#{params[:badge]}' users"
+ else
+ text = "All users"
+ end
+ text += " that contain '#{params[:search]}'" if params[:search]
+ %>
+ <%= title text %>
+ <% if params[:search] %>
+ (<%= @users.select {|u| u.name.downcase.include?(params[:search].downcase) || u.ign.downcase.include?(params[:search].downcase) }.size %>)
<% else %>
- <%= title "All Users" %>
+ (<%= @count %>)
<% end %>
- (<%= @count %>)
+
</h1>
<%= link_to "show all", users_path if params[:role] || params[:badge] %>
diff --git a/config/routes.rb b/config/routes.rb
index f79ab5b..4db3f30 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -27,14 +27,19 @@ Redstoner::Application.routes.draw do
get 'lost_password'
post 'reset_password'
post 'suggestions'
+ post 'search_redirect'
end
end
resources :forumgroups, path: '/forums/groups'
- resources :forums, path: '/forums'
resources :forumthreads, path: '/forums/threads' do
resources :threadreplies, path: 'replies'
+ collection do
+ get 'search'
+ post 'search_redirect'
+ end
end
+ resources :forums, path: '/forums'
resources :tools do
collection do
diff --git a/db/migrate/20170522210610_add_search_indexes.rb b/db/migrate/20170522210610_add_search_indexes.rb
new file mode 100644
index 0000000..2225d7b
--- /dev/null
+++ b/db/migrate/20170522210610_add_search_indexes.rb
@@ -0,0 +1,8 @@
+class AddSearchIndexes < ActiveRecord::Migration
+ def change
+ add_index :forumthreads, [:title, :content], type: :fulltext
+ add_index :forumthreads, :title, type: :fulltext
+ add_index :forumthreads, :content, type: :fulltext
+ add_index :threadreplies, :content, type: :fulltext
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 0a29b6b..aa35812 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20170515200733) do
+ActiveRecord::Schema.define(version: 20170522210610) do
create_table "blogposts", force: :cascade do |t|
t.string "title", limit: 191
@@ -65,6 +65,10 @@ ActiveRecord::Schema.define(version: 20170515200733) do
t.integer "label_id", limit: 4
end
+ add_index "forumthreads", ["content"], name: "index_forumthreads_on_content", type: :fulltext
+ add_index "forumthreads", ["title", "content"], name: "index_forumthreads_on_title_and_content", type: :fulltext
+ add_index "forumthreads", ["title"], name: "index_forumthreads_on_title", type: :fulltext
+
create_table "info", force: :cascade do |t|
t.string "title", limit: 191
t.text "content", limit: 65535
@@ -78,8 +82,8 @@ ActiveRecord::Schema.define(version: 20170515200733) do
end
create_table "register_tokens", force: :cascade do |t|
- t.string "uuid", limit: 191, null: false
- t.string "token", limit: 191, null: false
+ t.string "uuid", limit: 32, null: false
+ t.string "token", limit: 6, null: false
t.string "email", limit: 191, null: false
end
@@ -116,6 +120,8 @@ ActiveRecord::Schema.define(version: 20170515200733) do
t.datetime "updated_at"
end
+ add_index "threadreplies", ["content"], name: "index_threadreplies_on_content", type: :fulltext
+
create_table "users", force: :cascade do |t|
t.string "uuid", limit: 191, null: false
t.string "name", limit: 191, null: false