class Admin::PersonalPluginFieldsController < OrbitAdminController require 'fileutils' include Admin::PersonalPluginFieldsHelper before_action :set_personal_plugin_field, only: [:show, :edit , :update, :destroy, :fields_setting, :update_fields_setting,:generate_plugin] def index @personal_plugin_fields = PersonalPluginField.order_by(:created_at=>'desc').page(params[:page]).per(10) end def new @member = MemberProfile.find_by(:uid=>params['uid']) rescue nil @personal_plugin_field = PersonalPluginField.new end def create personal_plugin_field = PersonalPluginField.create(personal_plugin_field_params) redirect_to params[:referer_url] end def edit end def destroy @personal_plugin_field.destroy redirect_to admin_personal_plugin_fields_path(:page => params[:page]) end def update @personal_plugin_field.update_attributes(personal_plugin_field_params) @personal_plugin_field.save redirect_to params[:referer_url] end def fields_setting end def update_fields_setting field_params = params.require(:personal_plugin_field).permit! rescue {} @personal_plugin_field.update_attributes(field_params) @personal_plugin_field.save redirect_to params[:referer_url] end def generate_plugin template_dir_path = File.expand_path("../../../../template_generator/", __FILE__) + "/" cp_template_dir_path = "#{Rails.root}/tmp/#{@personal_plugin_field.module_name}/" FileUtils.rm_rf(cp_template_dir_path) FileUtils.cp_r(template_dir_path,cp_template_dir_path) dirs = Dir.glob("#{cp_template_dir_path}*/") files = Dir.glob("#{cp_template_dir_path}*").select { |fn| File.file?(fn) } in_use_locales = Site.first.in_use_locales yml_files = Dir.glob("#{cp_template_dir_path}config/locales/*.yml") yml_files.each do |yml_file| locale = yml_file.split("/").last.split(".yml").first yml_text = File.read(yml_file) translate_hash = {} @personal_plugin_field.primary_modal_fields.each do |field_value| if field_value[:field_name] && (field_value[:translation_name][locale].present? rescue false) translate_hash[field_value[:field_name]] = field_value[:translation_name][locale] end end @personal_plugin_field.related_modal_name.each_with_index do |related_modal_name,i| field_values = @personal_plugin_field.related_modal_fields[i].to_a rescue [] sub_hash = {} field_values.each do |field_value| if field_value[:field_name] && (field_value[:translation_name][locale].present? rescue false) sub_hash[field_value[:field_name]] = field_value[:translation_name][locale] end end if related_modal_name.present? && sub_hash.present? translate_hash[related_modal_name] = sub_hash end end col_name_translate_yaml = "" if translate_hash.present? col_name_translate_yaml = translate_hash.to_yaml.gsub("---\n", '') end blank_text = yml_text.split(/(\r\n|\n)/).select{|t| t.include?"col_name_translate_yaml"}.first.split('col_name_translate_yaml').first rescue "" col_name_translate_yaml = col_name_translate_yaml.gsub("\n","\n#{blank_text}") yml_text = yml_text.gsub("col_name_translate_yaml",col_name_translate_yaml) yml_text = yml_text.gsub("personal_plugin_template_translate",@personal_plugin_field.title_translations[locale]) File.open(yml_file,'w+') do |f| f.write(yml_text) end end @blank_text = " " slug_title = @personal_plugin_field.primary_modal_fields.select{|field_value| field_value[:slug_title] == "1" rescue false}.first[:field_name].to_s rescue "" plugin_template_related_files = @personal_plugin_field.primary_modal_fields.select{|field_value| field_value[:field_type] == "file" rescue false}.map{|v| v[:field_name]} plugin_template_related_files_text = plugin_template_related_files.to_s plugin_template_related_files_fields = plugin_template_related_files.map{|field_name| "has_many :#{field_name.pluralize}, :dependent => :destroy, :autosave => true\r\n" + "#{@blank_text}accepts_nested_attributes_for :#{field_name.pluralize}, :allow_destroy => true" }.join("\r\n#{@blank_text}") plugin_template = @personal_plugin_field.primary_modal_name backend_index_fields = @personal_plugin_field.backend_fields["index"] rescue [] backend_index_fields_contents = backend_index_fields.map do |field_name| if field_name == slug_title "<%= link_to #{plugin_template}.#{field_name}, page_for_#{plugin_template}(#{plugin_template}), target: \"blank\" %>\r\n " + "
\r\n " else "<%= #{plugin_template}.#{field_name} %>" end end col_name_to_show = @personal_plugin_field.frontend_fields["member_show"] rescue [] col_name_to_show_in_show_page = @personal_plugin_field.frontend_fields["show"] rescue [] col_name_to_show_in_index_page = @personal_plugin_field.frontend_fields["index"] rescue [] extra_translate_title = col_name_to_show_in_index_page.map{|field_name| #在個人外掛前台index頁面的欄位翻譯名稱hash ["th-#{field_name}","I18n.locale(\"#{@personal_plugin_field.module_name}.#{field_name}\")"] } col_fields = get_fields_text(@personal_plugin_field.primary_modal_fields) col_related_fields = @personal_plugin_field.related_modal_fields.map{|field_values| get_fields_text(field_values)} locale_fields = [] none_locale_fields = [] locale_fields_input_fields = [] none_locale_fields_input_fields = [] plugin_template_related = @personal_plugin_field.related_modal_name.select{|n| n.present?} plugin_template_related_main_field = @personal_plugin_field.related_modal_fields.map{|field_values| field_values.map{|field_value| field_value[:field_name]}.select{|t| t.present?}.first } @personal_plugin_field.primary_modal_fields.each do |field_value| field_name = field_value[:field_name] field_type = field_value[:field_type] next if field_name.blank? next if field_type == "file" if (field_value[:localize] == "1" rescue false) locale_fields << field_name input_field = generate_input_field(field_type,field_name,true) locale_fields_input_fields << input_field else none_locale_fields << field_name input_field = generate_input_field(field_type,field_name) none_locale_fields_input_fields << input_field end end @match_pattern = {"personal_plugin_template" => @personal_plugin_field.module_name, "plugin_template" => plugin_template, "plugin_template_related" => plugin_template_related, "plugin_template_related_files_fields" => plugin_template_related_files_fields, "col_name_to_show" => col_name_to_show.to_s, #在會員前台頁面的顯示欄位 "col_name_to_show_in_show_page" => col_name_to_show_in_show_page.to_s, #在個人外掛前台show頁面的顯示欄位 "col_name_to_show_in_index_page" => col_name_to_show_in_index_page.to_s, #在個人外掛前台index頁面的顯示欄位 "extra_translate_title" => extra_translate_title.map{|k,v| "\"#{k}\" => #{v}"}.join(", ").prepend("{").concat("}"), "col_fields" => col_fields, "col_related_fields" => col_related_fields, "plugin_template_file" => plugin_template_related_files, "plugin_template_sort_hash" => "nil", "col_name_to_show_in_index_page_arr" => col_name_to_show_in_index_page, "backend_index_fields" => backend_index_fields, "slug_title" => slug_title, "backend_index_fields_contents" => backend_index_fields_contents, "plugin_template_related_files_text" => plugin_template_related_files_text, "locale_fields" => locale_fields, "none_locale_fields" => none_locale_fields, "none_locale_fields_input_fields" => none_locale_fields_input_fields, "locale_fields_input_fields" => locale_fields_input_fields, "plugin_template_related_main_field" => plugin_template_related_main_field } max_length = @match_pattern.keys.map{|k| k.length}.max @match_pattern = @match_pattern.sort_by{|k,v| (v.class != Array) ? (max_length - k.length) : -k.length} @logs = [] replace_files(files) #Thread.new do dirs.each do |dir| replace_dir(dir) end #end render :html => @logs.join("
").html_safe#@match_pattern end def generate_input_field(field_type,field_name,localize = false) personal_plugin_template = @personal_plugin_field.module_name plugin_template = @personal_plugin_field.primary_modal_name input_field = "" field_value_text = "@#{plugin_template}.#{field_name}" field_name_text = ":#{field_name}" field_name_text = "locale" if localize if localize field_value_text = "@#{plugin_template}.#{field_name}_translations[locale]" end case field_type when "year" input_field = "<%= select_year((#{field_value_text} ? #{field_value_text}.to_i : DateTime.now.year), {:start_year => DateTime.now.year + 5, :end_year => 1930}, {:name => '#{plugin_template}[#{field_name}]',:class => 'span1'} ) %>" when "date" when "time" when "date_time" input_field = "<%= f.text_area #{field_name_text}, class: \"input-block-level ckeditor\", placeholder: t(\"#{personal_plugin_template}.#{field_name}\"), value: (#{field_value_text} rescue nil) %>" when "text_editor" else #text_field input_field = "<%= f.text_field #{field_name_text}, class: \"input-block-level\", placeholder: t(\"#{personal_plugin_template}.#{field_name}\"), value: (#{field_value_text} rescue nil) %>" end if localize input_field.prepend("<%= f.fields_for :#{field_name}_translations do |f| %>\r\n ").concat("<% end %>\r\n ") end input_field end def get_fields_text(field_values) fields_text = field_values.map do |field_value| next if field_value[:field_type] == "file" || field_value[:field_name].blank? type = "String" default = "\"\"" case field_value[:field_type] when "date" type = "Date" default = "Date.parse(DateTime.now.to_s)" when "time" type = "Time" default = "Time.now" when "date_time" type = "DateTime" default = "DateTime.now" end no_localize_types = ["date","time","date_time"] field_text = "field :#{field_value[:field_name]}, :type => #{type}, :default => #{default}" field_text += ", :localize => true" if field_value[:localize] && !no_localize_types.include?(field_value[:field_type]) field_text += ", as: :slug_title" if field_value[:slug_title] end fields_text.join("\r\n#{@blank_text}") end def replace_dirs(dirs) dirs.each do |dir| replace_dir(dir) end end def replace_dir(dir) dir = replace_file(dir) return true if dir.select{|d| d.present?}.blank? if dir.count > 1 replace_dirs(dir) else dir = dir[0] end sub_dirs = Dir.glob("#{dir}/*/") files = Dir.glob("#{dir}/*").select { |fn| File.file?(fn) } replace_files(files) if sub_dirs.present? sub_dirs.each do |sub_dir| replace_dir(sub_dir) end else return true end end def replace_files(files) files.each do |file| replace_file(file) end end def replace_file(file) isfile = File.file?(file) path = File.dirname(file) file_name = File.basename(file) new_filename = replace_text_with_pattern(file_name,true) if new_filename.blank? FileUtils.rm_rf("#{path}/#{file_name}") elsif file_name != new_filename if new_filename.class == Array new_filename.each do |f| FileUtils.cp_r("#{path}/#{file_name}", "#{path}/#{f}") end FileUtils.rm_rf("#{path}/#{file_name}") else FileUtils.mv("#{path}/#{file_name}", "#{path}/#{new_filename}") end end if new_filename.blank? return [""] else is_array = new_filename.class == Array new_filename = Array(new_filename) if isfile new_filename.each_with_index do |sub_file,i| next if File.extname(sub_file).match(/(png|jpg)/i) file_text = File.read("#{path}/#{sub_file}") if is_array file_text = replace_text_with_pattern(file_text,false,i) else file_text = replace_text_with_pattern(file_text) end File.open("#{path}/#{sub_file}",'w+'){|f| f.write(file_text)} end end return new_filename.map{|sub_file| "#{path}/#{sub_file}" if sub_file.present?} end end def replace_text_with_pattern(text,is_file=false,i = nil) new_text = text @match_pattern.each do |k,v| next if !include_key(new_text,k) vv = v vv = vv[i] if i && vv.class == Array if vv.class == String if i && vv == "" && is_file new_text = "" else new_text = gsub_text_by_key_value(new_text,k,vv) end elsif vv.class == Array if is_file if v.count == 0 new_text = "" break else new_text = vv.map{|sub_v| gsub_text_by_key_value(new_text,k,sub_v)} break end end new_text = new_text.gsub(/<% parse_again_start %>((?:(?!<% parse_again_start %>).)+)<% parse_again_end %>/m) do |ff| parse_content = $1 #last match result = ff if include_key($1,k) start_index = 0 end_index = parse_content.length start_index = 2 if parse_content[0..1] == "\r\n" end_index = end_index - 2 if parse_content[(end_index - 2)..(end_index - 1)] == "\r\n" parse_content = parse_content.slice(start_index,end_index) result = (0...vv.count).map {|i| replace_text_with_pattern(parse_content,false,i) }.join("") end result end end end return new_text end def include_key(text,key) return text.include?(key) || text.include?(key.classify) end def gsub_text_by_key_value(text,k,v) text = text.gsub(k + "s",v.pluralize) text = text.gsub(k ,v ) text = text.gsub(k.classify + "s",v.classify.pluralize) text = text.gsub(k.classify,v.classify) end private def personal_plugin_field_params personal_plugin_field_params = params.require(:personal_plugin_field).permit! rescue {} if personal_plugin_field_params[:related_modal_name].nil? personal_plugin_field_params[:related_modal_name] = [] end if personal_plugin_field_params[:primary_modal_fields] personal_plugin_field_params[:primary_modal_fields] = personal_plugin_field_params[:primary_modal_fields].values else personal_plugin_field_params[:primary_modal_fields] = [] end if personal_plugin_field_params[:related_modal_fields] personal_plugin_field_params[:related_modal_fields] = personal_plugin_field_params[:related_modal_fields].values.map{|h| h.values} else personal_plugin_field_params[:related_modal_fields] = [] end return personal_plugin_field_params end def set_personal_plugin_field path = request.path.split('/') if path.last.include? '-' uid = path[-1].split("-").last uid = uid.split("?").first else uid = path[-2].split("-").last uid = uid.split("?").first end @personal_plugin_field = PersonalPluginField.find_by(:uid => uid) rescue PersonalPluginField.find(params[:id] || params[:personal_plugin_field_id]) end end