200 lines
5.1 KiB
Ruby
200 lines
5.1 KiB
Ruby
class BookmarkSearchForm
|
|
|
|
extend ActiveModel::Naming
|
|
include ActiveModel::Conversion
|
|
include ActiveModel::Validations
|
|
|
|
ATTRIBUTES = [
|
|
:bookmark_query,
|
|
:bookmarkable_query,
|
|
:rec,
|
|
:bookmark_notes,
|
|
:with_notes,
|
|
:date,
|
|
:show_private,
|
|
:pseud_ids,
|
|
:user_ids,
|
|
:bookmarker,
|
|
:bookmarkable_pseud_names,
|
|
:bookmarkable_pseud_ids,
|
|
:bookmarkable_type,
|
|
:language_id,
|
|
:excluded_tag_names,
|
|
:excluded_bookmark_tag_names,
|
|
:excluded_tag_ids,
|
|
:excluded_bookmark_tag_ids,
|
|
:other_tag_names,
|
|
:other_bookmark_tag_names,
|
|
:tag_ids,
|
|
:filter_ids,
|
|
:filter_names,
|
|
:fandom_ids,
|
|
:character_ids,
|
|
:relationship_ids,
|
|
:freeform_ids,
|
|
:rating_ids,
|
|
:archive_warning_ids,
|
|
:category_ids,
|
|
:bookmarkable_title,
|
|
:bookmarkable_date,
|
|
:bookmarkable_complete,
|
|
:collection_ids,
|
|
:bookmarkable_collection_ids,
|
|
:sort_column,
|
|
:show_restricted,
|
|
:page,
|
|
:faceted
|
|
]
|
|
|
|
attr_accessor :options
|
|
|
|
ATTRIBUTES.each do |filterable|
|
|
define_method(filterable) { options[filterable] }
|
|
end
|
|
|
|
def initialize(options = {})
|
|
@options = processed_options(options)
|
|
@searcher = BookmarkQuery.new(@options)
|
|
end
|
|
|
|
def persisted?
|
|
false
|
|
end
|
|
|
|
# This is used by SearchHelper.search_header.
|
|
def query
|
|
queries = []
|
|
%w[bookmarkable_query bookmark_query].each do |key|
|
|
queries << options[key] if options[key].present?
|
|
end
|
|
queries.join(', ')
|
|
end
|
|
|
|
def summary
|
|
summary = []
|
|
%w[bookmarkable_query bookmark_query].each do |key|
|
|
if options[key].present?
|
|
summary << options[key]
|
|
end
|
|
end
|
|
if options[:bookmarker].present?
|
|
summary << "Bookmarker: #{options[:bookmarker]}"
|
|
end
|
|
if options[:notes].present?
|
|
summary << "Notes: #{options[:notes]}"
|
|
end
|
|
tags = []
|
|
%w[other_tag_names other_bookmark_tag_names].each do |key|
|
|
if options[key].present?
|
|
tags << options[key]
|
|
end
|
|
end
|
|
all_tag_ids = []
|
|
[:filter_ids, :fandom_ids, :rating_ids, :category_ids, :archive_warning_ids, :character_ids, :relationship_ids, :freeform_ids].each do |tag_ids|
|
|
if options[tag_ids].present?
|
|
all_tag_ids += options[tag_ids]
|
|
end
|
|
end
|
|
unless all_tag_ids.empty?
|
|
tags << Tag.where(id: all_tag_ids).pluck(:name).join(", ")
|
|
end
|
|
unless tags.empty?
|
|
summary << "Tags: #{tags.uniq.join(", ")}"
|
|
end
|
|
if self.bookmarkable_type.present?
|
|
summary << "Type: #{self.bookmarkable_type}"
|
|
end
|
|
if self.language_id.present?
|
|
language = Language.find_by(short: self.language_id)
|
|
if language.present?
|
|
summary << "Work language: <span lang=#{language.short}>#{language.name}</span>"
|
|
end
|
|
end
|
|
if %w(1 true).include?(self.rec.to_s)
|
|
summary << "Rec"
|
|
end
|
|
if %w(1 true).include?(self.with_notes.to_s)
|
|
summary << "With Notes"
|
|
end
|
|
[:date, :bookmarkable_date].each do |countable|
|
|
if options[countable].present?
|
|
desc = (countable == :date) ? "Date bookmarked" : "Date updated"
|
|
summary << "#{desc}: #{options[countable]}"
|
|
end
|
|
end
|
|
summary.join(", ")
|
|
end
|
|
|
|
def search_results
|
|
@searcher.search_results
|
|
end
|
|
|
|
# Special function for returning the BookmarkableQuery results (instead of
|
|
# the BookmarkQuery results).
|
|
def bookmarkable_search_results
|
|
@searcher.bookmarkable_query.search_results
|
|
end
|
|
|
|
###############
|
|
# SORTING
|
|
###############
|
|
|
|
def sort_options
|
|
[
|
|
['Date Bookmarked', 'created_at'],
|
|
['Date Updated', 'bookmarkable_date'],
|
|
]
|
|
end
|
|
|
|
def sort_values
|
|
sort_options.map{ |option| option.last }
|
|
end
|
|
|
|
def sort_direction(sort_column)
|
|
'desc'
|
|
end
|
|
|
|
private
|
|
|
|
def processed_options(opts = {})
|
|
[:date, :bookmarkable_date].each do |countable|
|
|
if opts[countable].present?
|
|
opts[countable] = opts[countable].gsub(">", ">").
|
|
gsub("<", "<")
|
|
end
|
|
end
|
|
|
|
# If we call the form field 'notes', the parser adds html to it
|
|
opts[:notes] = opts[:bookmark_notes]
|
|
|
|
opts = standardize_language_ids(opts)
|
|
|
|
# Support legacy warning searches
|
|
if opts[:warning_ids].present?
|
|
opts[:archive_warning_ids] = opts.delete(:warning_ids)
|
|
end
|
|
|
|
# We need to respect some options that are deliberately set to false, and
|
|
# false.blank? is true, so we check for nil? and not blank? here.
|
|
opts.delete_if { |_, v| v.nil? }
|
|
end
|
|
|
|
# Maintain backward compatibility for old bookmark searches/filters:
|
|
def standardize_language_ids(opts)
|
|
# - Using language IDs in the "Work language" dropdown
|
|
if opts[:language_id].present? && opts[:language_id].to_i != 0
|
|
language = Language.find_by(id: opts[:language_id])
|
|
opts[:language_id] = language.short if language.present?
|
|
end
|
|
|
|
# - Using language IDs in "Any field on work" (search) or "Search within results" (filters)
|
|
if opts[:bookmarkable_query].present?
|
|
opts[:bookmarkable_query] = opts[:bookmarkable_query].gsub(/\blanguage_id\s*:\s*(\d+)/) do
|
|
lang = Language.find_by(id: Regexp.last_match[1])
|
|
lang = Language.default if lang.blank?
|
|
"language_id: " + lang.short
|
|
end
|
|
end
|
|
opts
|
|
end
|
|
end
|