class UniversalTablesController < ApplicationController include Admin::UniversalTablesHelper FrontendMethods = ["mind_map"] def index params = OrbitHelper.params if params[:layout_type] == "mindmap" index_mind_maps else index_entries end end def export_filtered table = UTable.where(:category_id => params[:cat]).first rescue nil page = Page.where(:page_id => params[:page_id]).first return unless table host_url = Site.first.root_url host_url = request.protocol + request.host_with_port if host_url == "http://" @rows = [] @tablecolumns = [] # 處理 file 欄位雙欄輸出(連結與註解) table.table_columns.where(display_in_index: true).asc(:order).each do |column| if column.type == "file" @tablecolumns << column @tablecolumns << column.dup.tap { |c| c.define_singleton_method(:_file_title_column?) { true } } else @tablecolumns << column end end entries = get_entries(params, table, page, false) entries.each do |te| cols = [] @tablecolumns.each do |column| # 跳過副註解欄(由主 file 欄處理) if column.respond_to?(:_file_title_column?) && column._file_title_column? next end ce = te.column_entries.where(table_column_id: column.id).first rescue nil if ce.present? case column.type when "text" cols << { "text" => ce.text.to_s } when "integer" cols << { "text" => ce.number.to_s } when "editor" cols << { "text" => ce.content.to_s } when "date" cols << { "text" => format_date(ce.date, column.date_format).to_s } when "period" from = format_date(ce.period_from, column.date_format) to = format_date(ce.period_to, column.date_format) text = from.blank? && to.present? ? to : "#{from} ~ #{to}" cols << { "text" => text.to_s } when "image" text = ce.image.thumb.url ? (host_url + ce.image.thumb.url) : "" cols << { "text" => text } when "file" file_links = [] file_titles = [] 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) title = if entry_file.respond_to?(:file_title_translations) && entry_file.file_title_translations.is_a?(Hash) entry_file.file_title_translations[locale] elsif entry_file.file_title.is_a?(Hash) entry_file.file_title[locale] else entry_file.file_title end title = entry_file.file.filename.to_s if title.blank? file_titles << title end cols << { "text" => file_links.join("\r\n") } cols << { "text" => file_titles.join("\r\n") } else cols << { "text" => "" } end else if column.type == "file" cols << { "text" => "" } cols << { "text" => "" } else cols << { "text" => "" } end end end @rows << { "columns" => cols } end excel_name = "#{table.title}.xlsx" excel_name = 'attachment; filename="' + excel_name + '"' 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") case column.type when "text" columns = column.column_entries.any_of([{"text.en" => regex}, {"text.zh_tw" => regex}]) when "editor" columns = column.column_entries.any_of([{"content.en" => regex}, {"content.zh_tw" => regex}]) when "file" column_ids = column.column_entries.pluck(:id) filtered_column_ids = ColumnEntryFile.where(:column_entry_id.in => column_ids).any_of([{ "file_title.en" => regex },{"file_title.zh_tw" => regex }]).pluck(:column_entry) columns = ColumnEntry.where(:id.in => filtered_column_ids) 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 if !params[:orbithashtag].present? entries = TableEntry.where(:u_table_id=>table.id, "have_data.#{I18n.locale}" => {"$in" => [nil, true]}).can_display.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]}).filter_by_hashtag(OrbitHelper.page_hashtag_id).can_display.sorting(params: params,table: table,page_num: params["page_no"],per: OrbitHelper.page_data_count) end else if !params[:orbithashtag].present? entries = TableEntry.where(:u_table_id=>table.id, "have_data.#{I18n.locale}" => {"$in" => [nil, true]}).can_display.sorting(params: params,table: table,paginated: false) else entries = TableEntry.where(:u_table_id=>table.id, "have_data.#{I18n.locale}" => {"$in" => [nil, true]}).filter_by_hashtag(OrbitHelper.page_hashtag_id).can_display.sorting(params: params,table: table,paginated: false) end 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 next if ct.nil? 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"] } sorted << { "title" => t("universal_table.hashtags"), "text" => entry.hashtags_for_frontend } entry.inc(view_count: 1) related_entries = [] entry.get_related_entries.each do |e| rows = [] e.column_entries.each do |ce| ct = ce.table_column next if ct.nil? next if ct.display_in_index === false text = ce.get_frontend_text(ct) if ct.is_link_to_show text = "#{text}" end rows << { "title" => ct.title, "text" => text, "url" => OrbitHelper.url_to_show(e.to_param) } if text != "" end rows << { "title" => t("universal_table.hashtags"), "text" => e.tags_for_frontend } related_entries << { "related_entry" => rows } end { "entry" => sorted, "related_entries" => related_entries, "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 def index_entries 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 = "" csrf_input = "" have_serial_number = (page.layout != 'index1') tablecolumns = table.table_columns.where(:display_in_index => true).asc(:order) table_heads = tablecolumns.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}" 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","file" 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}" end when "integer" if tc.make_categorizable select_values = tc.column_entries.distinct(:number) form_field = "#{csrf_input}" 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 rows = [] entries = get_entries(params, table, page) total_pages = entries.total_pages table_heads << { "title" => t("universal_table.hashtags"), "type" => "hashtag", "key" => "", "search" => "hide", "form-field" => "", "sort" => "hide", "sort-class" => "sort hide", "sort-url" => "", "title-class" => " no-search" } 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 = "#{text}" end cols << {"text" => text} else cols << {"text" => ""} end end text = te.hashtags_for_frontend cols << {"text" => text} 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 = "Export" 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 index_mind_maps 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 mindmaps = [] mms = Kaminari.paginate_array(table.mind_maps).page(params["page_no"]).per(OrbitHelper.page_data_count) mms.each do |mindmap| mindmaps << { "title" => mindmap.title, "url" => OrbitHelper.url_to_show("-" + mindmap.uid) + "?method=mind_map" } end { "mindmaps" => mindmaps, "total_pages" => mms.total_pages, "extras" => { "table-name" => table.title } } end def mind_map params = OrbitHelper.params mindmap = MindMap.where(:uid => params["uid"]).first { "title" => mindmap.title, "mind_map_data" => mindmap.mind_map_data } end def tag_cloud tables = UTable.filter_by_widget_categories(OrbitHelper.widget_categories,false) tags = TableTag.where(:u_table_id.in => tables.pluck(:id)) hashtags = tags.map do |tag| { "title" => "##{tag.title}", "count" => tag.table_entries.count, "url_to_show" => "#{OrbitHelper.widget_more_url}?tag=#{tag.title}" } end { "hashtags" => hashtags, "extras" => {} } end end