354 lines
11 KiB
Ruby
354 lines
11 KiB
Ruby
class UniversalTablesController < ApplicationController
|
|
include Admin::UniversalTablesHelper
|
|
def index
|
|
params = OrbitHelper.params
|
|
table = UTable.where(:category_id => OrbitHelper.page_categories.first).first rescue nil
|
|
page = OrbitHelper.page rescue Page.where(:page_id => params[:page_id]).first
|
|
searchable_columns = []
|
|
if !table.nil?
|
|
reset = "hide"
|
|
csrf_value = (0...46).map { ('a'..'z').to_a[rand(26)] }.join
|
|
params_q = params["q"].to_h.each{|_, v| v.gsub!("\"", '')} rescue {}
|
|
params_no = params["page_no"].to_s.gsub("\"",'')
|
|
if params_q.present?
|
|
query_string = '&' + params_q.map{|k, v| ["q[#{k}]",v]}.to_h.to_query
|
|
else
|
|
query_string = ''
|
|
end
|
|
query_string += "&page_no=#{params_no}" if params_no.present?
|
|
csrf_input = "<input type=\"hidden\" name=\"authenticity_token\" value=\"#{csrf_value}\">"
|
|
have_serial_number = (page.layout != 'index1')
|
|
table_heads = table.table_columns.where(:display_in_index => true).asc(:order).collect do |tc|
|
|
field_key = tc.key
|
|
field_value = params_q[field_key]
|
|
field_value = nil if field_value.blank?
|
|
search = ""
|
|
sort_class = "sort"
|
|
sort = ""
|
|
form_field = "#{csrf_input}<input type=\"search\" class=\"form-control\" name=\"q[#{field_key}]\" value=\"#{field_value}\" placeholder=\"Search keyword\">"
|
|
sort_url = "/#{I18n.locale.to_s}#{page.url}?sortcolumn=#{field_key}&sort=asc#{query_string}"
|
|
title_class = ""
|
|
case tc.type
|
|
when "date"
|
|
search = "hide"
|
|
when "period","image"
|
|
sort_class = "sort hide"
|
|
search = "hide"
|
|
sort_url = "#"
|
|
sort = "hide"
|
|
when "editor"
|
|
sort_url = "#"
|
|
sort = "hide"
|
|
sort_class = "sort hide"
|
|
when "text"
|
|
if tc.make_categorizable
|
|
select_values = tc.column_entries.distinct("text.#{I18n.locale.to_s}")
|
|
form_field = "#{csrf_input}<select class=\"form-control\" name=\"q[#{field_key}]\">"
|
|
if field_value.nil?
|
|
select_values.insert(0, "")
|
|
end
|
|
select_values.each do |sv|
|
|
if field_value && sv == field_value
|
|
selected = " selected"
|
|
else
|
|
selected = ""
|
|
end
|
|
form_field += "<option value=\"#{sv}\"#{selected}>#{sv}</option>"
|
|
end
|
|
form_field += "</select>"
|
|
end
|
|
when "integer"
|
|
if tc.make_categorizable
|
|
select_values = tc.column_entries.distinct(:number)
|
|
form_field = "#{csrf_input}<select class=\"form-control\" name=\"q[#{field_key}]\">"
|
|
if field_value.nil?
|
|
select_values.insert(0, "")
|
|
end
|
|
select_values.each do |sv|
|
|
if field_value && sv == field_value
|
|
selected = " selected"
|
|
else
|
|
selected = ""
|
|
end
|
|
form_field += "<option value=\"#{sv}\"#{selected}>#{sv}</option>"
|
|
end
|
|
form_field += "</select>"
|
|
end
|
|
end
|
|
|
|
if params["sortcolumn"] == field_key
|
|
sort_class = params["sort"] == "asc" ? "sort-desc" : "sort-asc"
|
|
sort_url = "/#{I18n.locale.to_s}#{page.url}?sortcolumn=#{field_key}&sort=#{params["sort"] == "asc" ? "desc" : "asc"}#{query_string}"
|
|
end
|
|
|
|
title_class = title_class + "no-sort" if sort == "sort"
|
|
title_class = title_class + " no-search" if search == "hide"
|
|
|
|
col_class = 'col-md-4 col-xs-12'
|
|
|
|
col = {
|
|
"title" => tc.title,
|
|
"type" => tc.type,
|
|
"key" => field_key,
|
|
"search" => search,
|
|
"form-field" => form_field,
|
|
"sort" => sort,
|
|
"sort-class" => sort_class,
|
|
"sort-url" => sort_url,
|
|
"title-class" => title_class,
|
|
"col-class" => col_class
|
|
}
|
|
if tc.is_searchable
|
|
searchable_columns << col
|
|
end
|
|
col
|
|
end
|
|
tablecolumns = table.table_columns.where(:display_in_index => true).asc(:order)
|
|
rows = []
|
|
entries = get_entries(params, table, page)
|
|
total_pages = entries.total_pages
|
|
if have_serial_number
|
|
page_no_offset = (params_no.present? ? [0, params_no.to_i - 1].max : 0)
|
|
serial_number_count = page_no_offset * OrbitHelper.page_data_count
|
|
table_heads.insert(0, {
|
|
"title" => "No.",
|
|
"type" => "",
|
|
"key" => "",
|
|
"search" => "hide",
|
|
"form-field" => "",
|
|
"sort" => "hide",
|
|
"sort-class" => "sort hide",
|
|
"sort-url" => "",
|
|
"title-class" => " no-search"
|
|
})
|
|
end
|
|
entries.each do |te|
|
|
cols = []
|
|
sort_value = ""
|
|
if have_serial_number
|
|
serial_number_count += 1
|
|
cols << {"text" => serial_number_count.to_s}
|
|
end
|
|
tablecolumns.each do |column|
|
|
ce = te.column_entries.where(:table_column_id => column.id).first rescue nil
|
|
if !ce.nil?
|
|
text = ce.get_frontend_text(column)
|
|
if column.is_link_to_show
|
|
text = "<a href='#{OrbitHelper.url_to_show("-" + te.uid)}'>#{text}</a>"
|
|
end
|
|
|
|
cols << {"text" => text}
|
|
else
|
|
cols << {"text" => ""}
|
|
end
|
|
end
|
|
rows << {
|
|
"columns" => cols
|
|
}
|
|
end
|
|
end
|
|
export_button = ""
|
|
if get_query(params).present?
|
|
reset = ""
|
|
if !OrbitHelper.current_user.nil?
|
|
p = {}
|
|
params.each do |k,v|
|
|
p[k] = v if ["q","column","sort","sortcolumn"].include?(k)
|
|
end
|
|
export_button = "<a href='/xhr/universal_table/export.xlsx?cat=#{OrbitHelper.page_categories.first}&page_id=#{page.page_id}&#{p.to_param}'>Export</a>"
|
|
end
|
|
total_entries = t("universal_table.total_number_of_entries", :total_number => entries.total_count)
|
|
elsif params["sortcolumn"].present?
|
|
reset = ""
|
|
end
|
|
{
|
|
"searchable-columns" => searchable_columns,
|
|
"head-columns" => table_heads,
|
|
"rows" => rows,
|
|
"total_pages" => total_pages,
|
|
"extras" => {
|
|
"total_entries" => total_entries,
|
|
"table-name" => table.title,
|
|
"export_button" => export_button,
|
|
"reset" => reset,
|
|
"url" => "/#{I18n.locale.to_s}#{page.url}"
|
|
}
|
|
}
|
|
end
|
|
|
|
def export_filtered
|
|
table = UTable.where(:category_id => params[:cat]).first rescue nil
|
|
page = Page.where(:page_id => params[:page_id]).first
|
|
if !table.nil?
|
|
host_url = Site.first.root_url
|
|
if host_url == "http://"
|
|
host_url = request.protocol + request.host_with_port
|
|
end
|
|
@rows = []
|
|
@tablecolumns = table.table_columns.where(:display_in_index => true).asc(:order)
|
|
entries = get_entries(params, table, page, false)
|
|
entries.each do |te|
|
|
cols = []
|
|
sort_value = ""
|
|
@tablecolumns.each do |column|
|
|
ce = te.column_entries.where(:table_column_id => column.id).first rescue nil
|
|
if !ce.nil?
|
|
text = ""
|
|
case ce.type
|
|
when "text"
|
|
text = ce.text
|
|
when "integer"
|
|
text = ce.number
|
|
when "editor"
|
|
text = ce.content
|
|
when "date"
|
|
text = format_date(ce.date, column.date_format)
|
|
when "period"
|
|
text = format_date(ce.period_from, column.date_format) + " ~ " + format_date(ce.period_to, column.date_format)
|
|
text = "" if text.starts_with?(" ~")
|
|
when "image"
|
|
text = host_url + ce.image.thumb.url
|
|
when "file"
|
|
file_links = []
|
|
locale = I18n.locale.to_s
|
|
ce.column_entry_files.desc(:sort_number).each do |entry_file|
|
|
next unless entry_file.choose_lang_display(locale)
|
|
file_links << (host_url + entry_file.get_link)
|
|
end
|
|
text = file_links.join("\r\n")
|
|
end
|
|
cols << {"text" => text}
|
|
else
|
|
cols << {"text" => ""}
|
|
end
|
|
end
|
|
@rows << {
|
|
"columns" => cols
|
|
}
|
|
end
|
|
excel_name = table.title + ".xlsx"
|
|
excel_name = 'attachment; filename="' + excel_name + '"'
|
|
|
|
end
|
|
respond_to do |format|
|
|
format.xlsx {
|
|
response.headers['Content-Disposition'] = excel_name
|
|
}
|
|
end
|
|
end
|
|
|
|
def get_query(params)
|
|
if params["column"].present?
|
|
q = {params["column"] => params["q"]}
|
|
else
|
|
q = params["q"]
|
|
end
|
|
if q.present?
|
|
q.map{|k,v| [k, v.to_s.strip] if v.present?}.compact.to_h
|
|
else
|
|
nil
|
|
end
|
|
end
|
|
|
|
def get_entries(params, table, page, paginated=true)
|
|
entries = []
|
|
q = get_query(params)
|
|
if q.present?
|
|
table_entry_ids = nil
|
|
q.each do |k, v|
|
|
column = table.table_columns.where(:key => k).first
|
|
next if column.nil?
|
|
# if column.make_categorizable
|
|
# regex = Regexp.new(".*"+v+".*", "i")
|
|
# else
|
|
# regexes = v.split(/\s+(?=(?:[^"]*"[^"]*")*[^"]*$)/)
|
|
# regex = Regexp.union(regexes.map{|word| Regexp.new(".*"+word+".*", "i")})
|
|
# end
|
|
regex = Regexp.new(".*"+v+".*", "i")
|
|
if column.type == "text"
|
|
columns = column.column_entries.any_of([{"text.en" => regex}, {"text.zh_tw" => regex}])
|
|
elsif column.type == "editor"
|
|
columns = column.column_entries.any_of([{"content.en" => regex}, {"content.zh_tw" => regex}])
|
|
end
|
|
# .or(:"content.en" => regex).or(:"content.zh_tw" => regex)
|
|
tmp = columns.pluck(:table_entry_id)
|
|
if table_entry_ids.nil?
|
|
table_entry_ids = tmp
|
|
else
|
|
table_entry_ids = table_entry_ids & tmp
|
|
end
|
|
end
|
|
if table_entry_ids.nil?
|
|
entries = TableEntry.where(:u_table_id=>table.id, "have_data.#{I18n.locale}" => {"$in" => [nil, true]})
|
|
else
|
|
entries = TableEntry.where(:id.in=> table_entry_ids, "have_data.#{I18n.locale}" => {"$in" => [nil, true]})
|
|
end
|
|
entries = TableEntry.sorted(entries: entries, params: params, table: table, paginated: paginated)
|
|
if paginated
|
|
entries = entries.page(params["page_no"]).per(OrbitHelper.page_data_count)
|
|
end
|
|
else
|
|
if paginated
|
|
entries = TableEntry.where(:u_table_id=>table.id, "have_data.#{I18n.locale}" => {"$in" => [nil, true]}).sorting(params: params,table: table,page_num: params["page_no"],per: OrbitHelper.page_data_count)
|
|
else
|
|
entries = TableEntry.where(:u_table_id=>table.id, "have_data.#{I18n.locale}" => {"$in" => [nil, true]}).sorting(params: params,table: table,paginated: false)
|
|
end
|
|
end
|
|
entries
|
|
end
|
|
|
|
def show
|
|
params = OrbitHelper.params
|
|
entry = TableEntry.where(:uid => params[:uid]).first rescue nil
|
|
rows = []
|
|
|
|
entry.column_entries.each do |ce|
|
|
ct = ce.table_column
|
|
text = ce.get_frontend_text(ct)
|
|
rows << {
|
|
"title" => ct.title,
|
|
"text" => text,
|
|
"order" => ct.order
|
|
} if text != ""
|
|
end
|
|
sorted = rows.sort{ |k,v| k["order"] <=> v["order"] }
|
|
entry.inc(view_count: 1)
|
|
{
|
|
"entry" => sorted,
|
|
"extras" => {
|
|
"view_count_head" => I18n.t("view_count"),
|
|
"view_count" => entry.view_count
|
|
}
|
|
}
|
|
end
|
|
|
|
def download_file
|
|
file_id = params[:file]
|
|
file = ColumnEntryFile.find(file_id) rescue nil
|
|
if !file.nil? && file.file.present?
|
|
file.inc(download_count: 1)
|
|
@url = file.file.url
|
|
begin
|
|
@path = file.file.file.file rescue ""
|
|
@filename = File.basename(@path)
|
|
@ext = @filename.split(".").last
|
|
if @ext == "png" || @ext == "jpg" || @ext == "bmp" || @ext == "pdf"
|
|
render "download_file",:layout=>false
|
|
else
|
|
if (current_site.accessibility_mode rescue false)
|
|
render "redirect_to_file",:layout=>false
|
|
else
|
|
user_agent = request.user_agent.downcase
|
|
@escaped_file_name = user_agent.match(/(msie|trident)/) ? CGI::escape(@filename) : @filename
|
|
send_file(@path, :type=>"application/octet-stream", :filename => @escaped_file_name, :x_sendfile=> true)
|
|
end
|
|
end
|
|
rescue
|
|
redirect_to @url
|
|
end
|
|
else
|
|
render :file => "#{Rails.root}/app/views/errors/404.html", :layout => false, :status => :not_found
|
|
end
|
|
end
|
|
end
|