diff options
Diffstat (limited to 'app/models/forumthread.rb')
-rw-r--r-- | app/models/forumthread.rb | 67 |
1 files changed, 32 insertions, 35 deletions
diff --git a/app/models/forumthread.rb b/app/models/forumthread.rb index 86823ac..9650e28 100644 --- a/app/models/forumthread.rb +++ b/app/models/forumthread.rb @@ -67,45 +67,42 @@ class Forumthread < ActiveRecord::Base 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 - + order_phrase = query || [title, content, reply].select(&:present?).join(" ") + user_id = user.try(:id).to_i + role_value = user.try(:role).to_i + can_read = "COALESCE(forum_role_read.value, 0) <= ? AND COALESCE(forumgroup_role_read.value, 0) <= ?" + # A user can view sticky threads in write-only forums without read permissions. + sticky_can_write = "sticky = true AND (COALESCE(forum_role_write.value, 0) <= ? AND COALESCE(forumgroup_role_write.value, 0) <= ?)" + match = "MATCH (title, forumthreads.content) AGAINST (?) OR MATCH (threadreplies.content) AGAINST (?)" + + threads = forum.try(:forumthreads) || Forumthread + + threads = threads.select("forumthreads.*", "(MATCH (title, forumthreads.content) AGAINST (#{Forumthread.sanitize(order_phrase)})) AS relevance", "(MATCH (threadreplies.content) AGAINST (#{Forumthread.sanitize(order_phrase)})) AS reply_rel") + + threads = threads.joins(forum: :forumgroup) + .joins("LEFT JOIN threadreplies ON forumthreads.id = threadreplies.forumthread_id") + .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") + + threads = threads.where("forumthreads.user_author_id = ? OR (#{can_read}) OR (#{sticky_can_write})", user_id, role_value, role_value, role_value, role_value) if query - threads = threads.where("MATCH (title, forumthreads.content) AGAINST (?) OR MATCH (threadreplies.content) AGAINST (?)", query, query) + threads = threads.where("#{match}", query[0..99], query[0..99]) 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") + threads = threads.where("MATCH (title) AGAINST (?)", title[0..99]) if title + threads = threads.where("MATCH (forumthreads.content) AGAINST (?)", content[0..99]) if content + threads = threads.where("MATCH (threadreplies.content) AGAINST (?)", reply[0..99]) if reply end - end + if label.try(:downcase) == "no label" + threads = threads.where(label: nil) + elsif l = Label.find_by(name: label) && label + threads = threads.where(label: l) + end + threads = threads.where(user_author: author) if author - threads = threads.order("sticky desc", "threadreplies.created_at desc", "forumthreads.created_at desc") if threads.order_values.empty? + threads = threads.group("forumthreads.id") - threads + order_phrase.presence ? threads.order("GREATEST(relevance, reply_rel) DESC") : threads.order("sticky desc", "threadreplies.created_at DESC", "forumthreads.created_at DESC") end end |