class Admin::PersonalPluginFieldsController < OrbitMemberController 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 download zip_path = "tmp/" FileUtils.mkdir_p(zip_path) if !Dir.exist?(zip_path) personal_plugin_field = PersonalPluginField.find(params[:personal_plugin_field_id]) rescue nil if personal_plugin_field zip_file_path = zip_path + "#{personal_plugin_field.module_name}.zip" zip_file= ZipFileGenerator.new(zip_path + personal_plugin_field.module_name ,zip_file_path) begin zip_file.write rescue File.delete(zip_path + "#{personal_plugin_field.module_name}.zip") zip_file.write end send_file(zip_file_path) end end def copy @member = MemberProfile.find_by(:uid=>params['uid']) rescue nil attributes = PersonalPluginField.find(params[:personal_plugin_field_id]).attributes rescue {} attributes = attributes.except("_id") copy_attributes = {} attributes.each do |k,v| if (PersonalPluginField.fields[k].options[:localize] rescue false) copy_attributes["#{k}_translations"] = v else copy_attributes[k] = v end end #render :html => attributes and return @personal_plugin_field = PersonalPluginField.new(copy_attributes) end def create personal_plugin_field = PersonalPluginField.create(personal_plugin_field_params) redirect_to admin_personal_plugin_fields_path 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 admin_personal_plugin_fields_path end def fields_setting end def update_fields_setting field_params = params.require(:personal_plugin_field).permit! rescue {} field_params[:fields_order] = field_params[:fields_order].map do |k, v| [k, v.sort_by{|k,vv| k.to_i}.map{|vv| vv[1].to_i}] end.to_h @personal_plugin_field.update_attributes(field_params) @personal_plugin_field.save redirect_to params[:referer_url] end def scan_word_block(word) words_idx = [] tmp = [] is_word = false word.split('').each_with_index do |w, i| if w.match(/\w/) if !is_word tmp << i is_word = true end elsif is_word tmp << i - 1 words_idx << tmp tmp = [] is_word = false end end if tmp.count == 1 tmp << word.length - 1 words_idx << tmp tmp = [] end last_idx = word.length - 1 new_res = [] words_idx_reverse = words_idx.reverse words_idx_reverse.each_with_index do |v, i| s = v[0] e = v[1] tmp_str = word[s..e] tmp = word[e+1..last_idx] need_find_quote = tmp.match(/['"]/) need_find_quote = need_find_quote ? need_find_quote[0] : nil tmp_str += tmp prev_word_range = words_idx_reverse[i + 1] start_idx = 0 if prev_word_range start_idx = prev_word_range[1] + 1 end if need_find_quote tmp = word[start_idx...s].match(/(,\s+|)[,#{need_find_quote}]+\s*$/) else tmp = word[start_idx...s].match(/(,\s+|)\s*$/) end if tmp tmp = tmp[0] tmp_str = tmp + tmp_str last_idx = s - 1 - tmp.length else last_idx = s - 1 end new_res << tmp_str end new_res.reverse 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) } begin in_use_locales = Site.first.in_use_locales primary_modal_fields = @personal_plugin_field.primary_modal_fields.select{|f| (f[:field_name].present? rescue false)} primary_modal_fields << {:field_name=>"authors", :translation_name=>{"zh_tw"=>"全部作者", "en"=>"Authors"}, :field_type=>"text_editor", :localize=>"1", :slug_title=>"0", :periodic_time=>"0"} if primary_modal_fields.select{|f| f[:field_name] == "authors"}.count == 0 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 = {} primary_modal_fields.each do |field_value| if (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 #sub_hash["modal_name"] = "關聯欄位翻譯" end author_name_translation = @personal_plugin_field.author_name_translations[locale] rescue "" I18n.with_locale(locale) do author_name_translation = I18n.t("personal_plugins.author") if author_name_translation.blank? end translate_hash["member_profile"] = author_name_translation col_name_translate_yaml = "" if translate_hash.present? col_name_translate_yaml = translate_hash.to_yaml.gsub("---\n", '') end yml_text = gsub_text_by_key_value(yml_text,"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 = primary_modal_fields.select{|field_value| field_value[:slug_title] == "1" rescue false}.first[:field_name].to_s rescue "" plugin_template_related_files = primary_modal_fields.select{|field_value| field_value[:field_type] == "file" rescue false}.map{|v| v[:field_name]} plugin_template_related_links = primary_modal_fields.select{|field_value| field_value[:field_type] == "link" rescue false}.map{|v| v[:field_name]} plugin_template_related_members = primary_modal_fields.select{|field_value| field_value[:field_type] == "member" rescue false}.map{|v| v[:field_name]} plugin_template_related_files_text = plugin_template_related_files.to_s plugin_template_related_links_text = plugin_template_related_links.to_s fields = plugin_template_related_files + plugin_template_related_links plugin_template_related_files_fields = fields.map{|field_name| "has_many :#{field_name.pluralize}, :dependent => :destroy, :autosave => true\n" + "accepts_nested_attributes_for :#{field_name.pluralize}, :allow_destroy => true" }.join("\n") plugin_template = @personal_plugin_field.primary_modal_name all_fields = primary_modal_fields.map{|f| f[:field_name]} + ["member_profile"] @personal_plugin_field.related_modal_name.each_with_index do |k,i| all_fields += @personal_plugin_field.related_modal_fields[i].to_a.map{|f| "#{k}.#{f[:field_name]}"} end @personal_plugin_field.frontend_fields.each do |k,v| @personal_plugin_field.frontend_fields[k] = v & all_fields end @personal_plugin_field.backend_fields.each do |k,v| @personal_plugin_field.backend_fields[k] = v & all_fields end date_fields = [] year_month_fields = [] date_time_fields = [] primary_modal_fields.each do |field_value| if (field_value[:field_type].present? rescue false) case field_value[:field_type] when "date" date_fields << field_value[:field_name] when "year_month" year_month_fields << field_value[:field_name] when "date_time" date_time_fields << field_value[:field_name] end end end @personal_plugin_field.related_modal_name.each_with_index do |k,i| @personal_plugin_field.related_modal_fields[i].to_a.each do |field_value| field_name = "#{k}.#{field_value[:field_name]}" if (field_value[:field_type].present? rescue false) case field_value[:field_type] when "date" date_fields << field_name when "year_month" year_month_fields << field_name when "date_time" date_time_fields << field_name end end end end backend_index_fields = @personal_plugin_field.backend_fields["index"].to_a rescue [] backend_index_fields_contents = backend_index_fields.map do |field_name| if field_name == slug_title "\n <%= link_to #{plugin_template}.#{field_name}, page_for_#{plugin_template}(#{plugin_template}), target: \"blank\" %>\n" + "
\n"+ " \n"+ "
\n " elsif date_fields.include?(field_name) "<%= #{plugin_template}.#{field_name}.strftime('%Y/%m/%d') rescue \"\" %>" elsif year_month_fields.include?(field_name) "<%= #{plugin_template}.#{field_name}.strftime('%Y/%m') rescue \"\" %>" elsif date_time_fields.include?(field_name) "<%= #{plugin_template}.#{field_name}.strftime('%Y/%m/%d %H:%M') rescue \"\" %>" elsif field_name.include?(".") "<%= #{plugin_template}.#{field_name} rescue \"\" %>" elsif fields.include?(field_name) || plugin_template_related_members.include?(field_name) || field_name == "member_profile" #file or link or member "<%= #{plugin_template}.display_field(\"#{field_name}\").html_safe rescue \"\" %>" else "<%= #{plugin_template}.#{field_name} %>" end end backend_profile_fields = @personal_plugin_field.backend_fields["profile"].to_a rescue [] backend_profile_fields_contents = backend_profile_fields.map do |field_name| if field_name == slug_title "\n <%= link_to #{plugin_template}.#{field_name}, page_for_#{plugin_template}(#{plugin_template}), target: \"blank\" %>\n" + "
\n"+ " \n"+ "
\n " elsif field_name.include?(".") "<%= #{plugin_template}.#{field_name} rescue \"\" %>" elsif fields.include?(field_name) || plugin_template_related_members.include?(field_name) || field_name == "member_profile" #file or link or member "<%= #{plugin_template}.display_field(\"#{field_name}\").html_safe rescue \"\" %>" else "<%= #{plugin_template}.#{field_name} %>" end end col_name_to_show = @personal_plugin_field.frontend_fields["member_show"].to_a rescue [] col_name_to_show_in_show_page = @personal_plugin_field.frontend_fields["show"].to_a rescue [] col_name_to_show_in_index_page = @personal_plugin_field.frontend_fields["index"].to_a rescue [] extra_translate_title = col_name_to_show_in_index_page.map{|field_name| #在個人外掛前台index頁面的欄位翻譯名稱hash ["th-#{field_name}","I18n.t(\"#{@personal_plugin_field.module_name}.#{field_name}\")"] } col_fields = get_fields_text(primary_modal_fields) col_related_fields = @personal_plugin_field.related_modal_fields.map{|field_values| get_fields_text(field_values)} 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| slug_titles = field_values.select{|field_value| (field_value[:slug_title] == "1" rescue false)} if slug_titles.count == 0 slug_titles = field_values end slug_titles.map{|field_value| field_value[:field_name]}.select{|t| t.present?}.first } locale_fields , none_locale_fields , locale_fields_input_fields,none_locale_fields_input_fields = get_input_fields(primary_modal_fields) related_locale_fields = [] related_none_locale_fields = [] related_locale_fields_input_fields = [] related_none_locale_fields_input_fields = [] @personal_plugin_field.related_modal_fields.each_with_index do |field_values,i| related_modal_name = @personal_plugin_field.related_modal_name[i] f1 , f2 , f3 , f4 = get_input_fields(field_values,related_modal_name,related_modal_name) related_locale_fields << f1 related_none_locale_fields << f2 related_locale_fields_input_fields << f3 related_none_locale_fields_input_fields << f4 end datetime_field_types_hash = {"year_month"=>"%Y/%m","date"=>"%Y/%m/%d","time"=>"%H:%M","date_time"=>"%Y/%m/%d %H:%M"} datetime_fields = primary_modal_fields.select{|field_value| datetime_field_types_hash.keys.include?(field_value[:field_type])}.map{|field_value| [field_value[:field_name],datetime_field_types_hash[field_value[:field_type]]] }.to_h value_case_codes = ["value = #{plugin_template}.send(field) rescue \"\"", "if field.include?(\".\")", "#{@blank_text}value = #{plugin_template}", "#{@blank_text}field.split(\".\").each{|f| value = value.send(f) rescue nil }", "end", "file_fields = #{plugin_template_related_files}", "link_fields = #{plugin_template_related_links}", "member_fields = #{plugin_template_related_members}", "if file_fields.include?(field)", "#{@blank_text}files = #{plugin_template}.send(field.pluralize)", "#{@blank_text}value = files.map do |file|", "#{@blank_text * 2}url = file.file.url", "#{@blank_text * 2}title = (file.title.blank? ? File.basename(file.file.path) : file.title)", "#{@blank_text * 2}\"
  • \#{title}
  • \"", "#{@blank_text}end", "#{@blank_text}value = value.join(\"\")", "elsif link_fields.include?(field)", "#{@blank_text}links = #{plugin_template}.send(field.pluralize)", "#{@blank_text}value = links.map do |link|", "#{@blank_text * 2}url = link.url", "#{@blank_text * 2}title = (link.title.blank? ? url : link.title)", "#{@blank_text * 2}\"
  • \#{title}
  • \"", "#{@blank_text}end", "#{@blank_text}value = value.join(\"\")", "elsif member_fields.include?(field)", "#{@blank_text}members = #{plugin_template}.send(field.pluralize)", "#{@blank_text}value = members.map{|m|", "#{@blank_text*2}path = OrbitHelper.url_to_plugin_show(m.to_param, 'member') rescue '#'", "#{@blank_text*2}((text_only rescue false) ? m.name : \"\#{m.name}\")", "#{@blank_text}}", "#{@blank_text}join_text = (text_only rescue false) ? \",\" : \"
    \"", "#{@blank_text}value = value.join(join_text)", "elsif field == \"member_profile\" || field == \"authors\"", "#{@blank_text}value = get_authors_show(#{plugin_template})", "end", "strftime_hash = #{datetime_fields}", "if strftime_hash.keys.include?(field)", "#{@blank_text}value = value.strftime(strftime_hash[field]) rescue value", "end" ].join("\n") enable_one_line_title = @personal_plugin_field.enable_one_line_title && @personal_plugin_field.one_line_title_format.present? tmp_title = enable_one_line_title ? "(title_is_paper_format ? #{plugin_template}.create_link : value)" : "value" display_field_code = value_case_codes + "\n" + "if field == \"#{slug_title}\"\n" + "#{@blank_text}link = OrbitHelper.url_to_plugin_show(#{plugin_template}.to_param,'#{@personal_plugin_field.module_name}')\n" + "#{@blank_text}tmp_title = #{tmp_title}\n"+ "#{@blank_text}value = link == '#' ? tmp_title : \"\#{tmp_title}\"\n" + "end\n" + "value" value_case_codes += "\nvalue" related_backend_index_fields = @personal_plugin_field.related_modal_fields.map{|field_values| field_values.map{|field_value| (field_value[:field_name] rescue nil)}.select{|t| t.present?} } related_backend_index_fields_contents = related_backend_index_fields.map.with_index{|field_names,i| related_modal_name = @personal_plugin_field.related_modal_name[i] field_names.map{|field_name| "<%= #{related_modal_name}.#{field_name} %>"} } member_methods_define = primary_modal_fields.select{|f| (f[:field_type] == "member" rescue false)}.map{|field_value| ["def #{field_value[:field_name].pluralize}", " MemberProfile.find(self.#{field_value[:field_name].singularize}_ids) rescue []", "end"] }.flatten date_time_strftime = {"date"=>"%Y/%m/%d","date_time"=>"%Y/%m/%d %H:%M","year_month"=>"%Y/%m"} periodic_methods_define = primary_modal_fields.select{|f| (f[:periodic_time] == "1" rescue false)}.map{|field_value| strftime_string = "" if date_time_strftime.keys.include?(field_value[:field_type]) strftime_string = ".strftime(\"#{date_time_strftime[field_value[:field_type]]}\")" end ["def #{field_value[:field_name]}", " #{field_value[:field_name]}_start = self.#{field_value[:field_name]}_start#{strftime_string} rescue \"\"", " #{field_value[:field_name]}_end = self.#{field_value[:field_name]}_end#{strftime_string} rescue \"\"", " \"\#{#{field_value[:field_name]}_start} ~ \#{#{field_value[:field_name]}_end}\"", "end"] }.flatten related_periodic_methods_define = @personal_plugin_field.related_modal_fields.map{|field_values| field_values.select{|f| (f[:periodic_time] == "1" rescue false)}.map{|field_value| strftime_string = "" if date_time_strftime.keys.include? field_value[:field_type] strftime_string = ".strftime(\"#{date_time_strftime[field_value[:field_type]]}\")" end ["def #{field_value[:field_name]}", " \"\#{self.#{field_value[:field_name]}_start#{strftime_string}} ~ \#{self.#{field_value[:field_name]}_end#{strftime_string}}\"", "end"] }.flatten } analysis_field_name = @personal_plugin_field.backend_fields[:analysis][0] rescue "" analysis_field_name = "year" if analysis_field_name.blank? analysis_field_input_fields = "" personal_plugin_template = @personal_plugin_field.module_name iterate_step_text = "1.minute" if analysis_field_name.present? field_type = primary_modal_fields.select{|f| f[:field_name] == analysis_field_name}.first[:field_type] rescue "date_time" analysis_field_input_fields = ["start","end"].map{|f| "<%=t(\"#{personal_plugin_template}.extend_translate.#{f}_#{field_type}\")%>" + generate_input_field(field_type,"#{analysis_field_name}_#{f}" ).gsub("<%= f.","<%= ").gsub(", :new_record => @#{plugin_template}.new_record?","") }.join("") if field_type == "date" || field_type == "date_time" iterate_step_text = "1.day" elsif field_type == "year" iterate_step_text = "1" end end period_fields = primary_modal_fields.select{|f| (f[:periodic_time] == "1" rescue false)}.map{|f| f[:field_name]} time_fields = primary_modal_fields.select{|f| f[:field_type] == "time"}.map{|f| f[:field_name]} before_save_codes = ""#time_fields.map{|f| "self.#{f} = parse_time(self.#{f}.strftime('%H:%M'))"}.join("\n") plugin_template_sort_hash = {} @personal_plugin_field.backend_fields[:sort_asc].to_a.each do |f| plugin_template_sort_hash[f.to_sym] = 1 end rescue nil @personal_plugin_field.backend_fields[:sort_desc].to_a.each do |f| plugin_template_sort_hash[f.to_sym] = -1 end rescue nil if @personal_plugin_field.backend_fields[:sort_desc].to_a.count != 0 plugin_template_sort_hash[:id] = -1 end all_fields_types = { "member_profile"=>"authors", "authors" => "authors" } all_fields_to_show = [] @personal_plugin_field.primary_modal_fields.each do |f| field_name = f[:field_name] if field_name.present? all_fields_types[field_name] = f[:field_type] all_fields_to_show << field_name end end @personal_plugin_field.related_modal_name.each_with_index do |k,i| @personal_plugin_field.related_modal_fields[i].to_a.map do |f| field_name = f[:field_name] if field_name.present? field_name = "#{k}.#{field_name}" all_fields_types[field_name] = f[:field_type] all_fields_to_show << field_name end end end all_fields_to_show_in_index = @personal_plugin_field.get_sorted_fields(:frontend_fields, :index, all_fields_to_show) one_line_title_format_code = [] scan_code = scan_word_block(@personal_plugin_field.one_line_title_format) one_line_title_format_code << "title = ''" scan_code.each do |c| left_space = c.match(/^[\s\'\",]+/) right_space = c.match(/[\s\'\",]+$/) variable_name = c.sub(/^[\s\'\",]+/,'').sub(/[\s\'\",]+$/, '') if variable_name.present? field_type = all_fields_types[variable_name] if field_type if_condition = "if self.#{variable_name}.present?" variable_contents = "self.#{variable_name}" if field_type == 'date' || field_type == 'year_month' || field_type == 'date_time' variable_contents += ".strftime('%b. %Y')" elsif field_type == 'year' variable_contents += '.to_s' elsif field_type == 'member' variable_contents = "MemberProfile.where(:id.in=>self.#{variable_name}_ids).pluck(:tmp_name).map{|h| h[I18n.locale]}.to_sentence({:locale=>:en})" elsif field_type == 'authors' variable_contents = "get_authors_text(self, true, :en)" if_condition += ' || self.member_profile_id.present?' end if left_space || right_space left_space = left_space ? left_space[0] : '' right_space = right_space ? right_space[0] : '' one_line_title_format_code << "title += \"#{left_space.gsub('"','\\"')}\#{#{variable_contents}}#{right_space.gsub('"','\\"')}\" #{if_condition}" else one_line_title_format_code << "title += #{variable_contents} #{if_condition}" end end end end one_line_title_format_code << "title.sub(/^\\s*,/,'').gsub(/,(\\s*,)+/,',')" one_line_title_format_code = one_line_title_format_code.join("\n") col_name_to_show_short = [] col_name_to_show_short << analysis_field_name col_name_to_show_short << slug_title @match_pattern = {"personal_plugin_template" => personal_plugin_template, "plugin_template" => plugin_template, "plugin_template_related" => plugin_template_related, "plugin_template_related_files_fields" => plugin_template_related_files_fields, "all_fields_to_show" => all_fields_to_show , #所有該模組的欄位 "all_fields_to_show_in_index" => all_fields_to_show_in_index , #所有該模組的欄位在前台index頁面 "col_name_to_show_short" => col_name_to_show_short.to_s, #在會員前台頁面的顯示欄位 "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_link" => plugin_template_related_links, "plugin_template_sort_hash" => plugin_template_sort_hash.to_s, "col_name_to_show_in_index_page_arr" => col_name_to_show_in_index_page, "related_backend_index_fields" => related_backend_index_fields, "related_backend_index_fields_contents" => related_backend_index_fields_contents, "backend_index_fields" => backend_index_fields, "backend_index_fields_contents" => backend_index_fields_contents, "plugin_template_related_links_text" => plugin_template_related_links_text, "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, "related_locale_fields" => related_locale_fields, "related_none_locale_fields" => related_none_locale_fields, "related_none_locale_fields_input_fields" => related_none_locale_fields_input_fields, "related_locale_fields_input_fields" => related_locale_fields_input_fields, "plugin_template_related_main_field" => plugin_template_related_main_field, "backend_profile_fields" => backend_profile_fields, "backend_profile_fields_contents" => backend_profile_fields_contents, "value_case_codes" => value_case_codes, "display_field_code" => display_field_code, "member_methods_define" => member_methods_define, "analysis_field_name" => analysis_field_name, "analysis_field_input_fields" => analysis_field_input_fields, "before_save_codes" => before_save_codes, "time_fields_text" => time_fields.to_s, "iterate_step_text" => iterate_step_text, "plugin_template_related_members" => plugin_template_related_members.to_s, "periodic_methods_define" => periodic_methods_define, "related_periodic_methods_define" => related_periodic_methods_define, "period_fields_text" => period_fields.to_s, "enable_one_line_title" => enable_one_line_title.to_s, "one_line_title_format_code" => one_line_title_format_code, "is_one_line_title" => (enable_one_line_title ? [true] : []), #used in parse_again block if condition "slug_title_text" => slug_title } max_length = @match_pattern.keys.map{|k| k.length}.max @match_pattern = @match_pattern.sort_by{|k,v| -k.length} #sort_by{|k,v| (v.class != Array) ? (max_length - k.length) : -k.length} @logs = [] replace_files(files) #Thread.new do replace_dirs(dirs,false) #end copy_templates("#{cp_template_dir_path}modules/#{@personal_plugin_field.module_name}/") #render :html => @logs#@match_pattern#@logs.join("
    ").html_safe#@match_pattern @personal_plugin_field.update(:log_text=>"") @personal_plugin_field.update(:finished=>true) add_plugin("downloaded_extensions.rb",@personal_plugin_field.module_name) bundle_install render :json => {:success=>true,:url=>"/admin/#{plugin_template.pluralize}/",:name=>@personal_plugin_field.title} rescue => e @match_pattern = {"parse_again_start"=>"","parse_again_end"=>"","col_name_translate_yaml"=>""} replace_files(files) replace_dirs(dirs,false) error = e.backtrace.join("
    ") @personal_plugin_field.update(:log_text=>error) @personal_plugin_field.update(:finished=>false) render :json => {:success=>false,:error=>error} end end def copy_templates(source) templates = Dir.glob('app/templates/*/').select{|f| File.basename(f) != 'mobile'} templates.each do |template| FileUtils.cp_r(source,"#{template}modules/.") end end def get_input_fields(field_values,extra_field_name=nil,plugin_template = nil) none_locale_fields = [] locale_fields = [] locale_fields_input_fields = [] none_locale_fields_input_fields = [] @index = 0 field_values.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" || field_type == "link" localize = (field_value[:localize] == "1" rescue false) periodic = (field_value[:periodic_time] == "1" rescue false) input_field = generate_input_field(field_type,field_name,localize,extra_field_name,plugin_template,periodic) if localize locale_fields << field_name locale_fields_input_fields << input_field else none_locale_fields << field_name none_locale_fields_input_fields << input_field end @index += 1 end return locale_fields , none_locale_fields , locale_fields_input_fields,none_locale_fields_input_fields end def generate_input_field(field_type,field_name,localize = false,extra_field_name = nil, plugin_template = nil,periodic = false) personal_plugin_template = @personal_plugin_field.module_name plugin_template = @personal_plugin_field.primary_modal_name if plugin_template.nil? input_field = "" field_value_text = "@#{plugin_template}.#{field_name}" field_name_text = "\"#{field_name}\"" field_name_text = "locale" if localize org_field_name = field_name if periodic if localize field_name = "periodic_time_field" else field_name_text = "\"periodic_time_field\"" end end placeholder = "#{personal_plugin_template}.#{field_name}" placeholder = "#{personal_plugin_template}.#{extra_field_name}.#{field_name}" if extra_field_name if localize field_value_text = "@#{plugin_template}.#{field_name}_translations[locale]" end case field_type when "year" input_field = datetime_picker_text(plugin_template,field_name_text, "yyyy")#"<%= 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 "year_month" input_field = datetime_picker_text(plugin_template,field_name_text, "yyyy/MM") when "date" input_field = datetime_picker_text(plugin_template,field_name_text, "yyyy/MM/dd") when "time" input_field = datetime_picker_text(plugin_template,field_name_text, "HH:mm",true) when "date_time" input_field = datetime_picker_text(plugin_template,field_name_text) when "text_editor" input_field = "<%= f.text_area #{field_name_text}, class: \"input-block-level ckeditor\", placeholder: t(\"#{placeholder}\"), value: (#{field_value_text} rescue nil) %>" when "member" input_field = "<%= render partial: 'admin/member_selects/email_selection_box', locals: {field: '#{plugin_template}[#{field_name.singularize}_ids][]', email_members: @#{plugin_template}.#{field_name.pluralize},index:'#{@index}',select_name:'#{field_name.pluralize}'} %>" else #text_field input_field = "<%= f.text_field #{field_name_text}, class: \"input-block-level\", placeholder: t(\"#{placeholder}\"), value: (#{field_value_text} rescue nil) %>" end if localize input_field.prepend("<%= f.fields_for :#{field_name}_translations do |f| %>\n ").concat("\n<% end %>") end if periodic input_fields = [] input_fields[0] = input_field.gsub("periodic_time_field","#{org_field_name}_start") input_fields[1] = input_field.gsub("periodic_time_field","#{org_field_name}_end") input_field = ["start","end"].map.with_index{|f,i| "<%=t(\"#{personal_plugin_template}.extend_translate.#{f}_#{field_type}\")%>" + input_fields[i] }.join("") end input_field end def datetime_picker_text(plugin_template,field_name_text,format = "yyyy/MM/dd hh:mm",timepicker = false) extra_txt = "" extra_txt = ":picker_type => \"time\"," if timepicker "<%= f.datetime_picker #{field_name_text},:format => \"#{format}\",#{extra_txt} :no_label => true, :new_record => @#{plugin_template}.new_record? %>" 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_type] == "link" || field_value[:field_name].blank? type = "String" default = "\"\"" field_name = field_value[:field_name] case field_value[:field_type] when "year" type = "Integer" default = "DateTime.now.year" when "date" type = "Date" default = "Date.today" when "time" type = "String" default = "\"\"" when "date_time" type = "DateTime" default = "DateTime.now" when "year_month" type = "DateTime" default = "DateTime.now" when "member" type = "Array" default = "[]" field_name = "#{field_name.singularize}_ids" end no_localize_types = ["date","time","date_time","year_month"] field_text = "" if field_value[:periodic_time] == "1" && no_localize_types.include?(field_value[:field_type]) field_text = [] field_text[0] = "field :#{field_name}_start, :type => #{type}, :default => #{default}" field_text[0] += ", :localize => true" if field_value[:localize] == "1" && !no_localize_types.include?(field_value[:field_type]) field_text[0] += ", as: :slug_title" if field_value[:slug_title] == "1" field_text[1] = "field :#{field_name}_end, :type => #{type}, :default => #{default}" field_text[1] += ", :localize => true" if field_value[:localize] == "1" && !no_localize_types.include?(field_value[:field_type]) field_text[1] += ", as: :slug_title" if field_value[:slug_title] == "1" else field_text = "field :#{field_name}, :type => #{type}, :default => #{default}" field_text += ", :localize => true" if field_value[:localize] == "1" && !no_localize_types.include?(field_value[:field_type]) field_text += ", as: :slug_title" if field_value[:slug_title] == "1" end field_text end fields_text = fields_text.flatten fields_text.select{|t| t.present?}.join("\n") end def replace_dirs(dirs,is_array = true) dirs.each_with_index do |dir,i| if is_array replace_dir(dir,i) else replace_dir(dir) end end end def replace_dir(dir,current_index = nil) dir = replace_file(dir,current_index) return true if dir.blank? if dir.class == Array replace_dirs(dir) return true end sub_dirs = Dir.glob("#{dir}/*/") files = Dir.glob("#{dir}/*").select { |fn| File.file?(fn) } replace_files(files,current_index) if sub_dirs.present? sub_dirs.each do |sub_dir| replace_dir(sub_dir,current_index) end else return true end end def replace_files(files,current_index = nil) files.each do |file| replace_file(file,current_index) end end def replace_file(file,current_index = nil) 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| next if f.blank? 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 if isfile files = Array(new_filename) files.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,nil,true) elsif current_index file_text = replace_text_with_pattern(file_text,false,current_index,nil,true) else file_text = replace_text_with_pattern(file_text) end File.open("#{path}/#{sub_file}",'w+'){|f| f.write(file_text)} end end if is_array return new_filename.map{|sub_file| "#{path}/#{sub_file}" if sub_file.present?}.select{|f| f.present?} else return "#{path}/#{new_filename}" end end end def replace_text_with_pattern(text,is_file=false,i = nil,sub_i = nil,inner = false) 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 vv = vv[sub_i] if sub_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(/[ \t]*parse_again_start((?:(?!parse_again_start).)+)parse_again_end[ \t]*(\r\n|\n|$)/m) do |ff| @parse_again_mode = true parse_content = $1 #parse_again block contents result = ff match_count = parse_content.match(/^ *\* *\d+/m) match_count = match_count ? match_count[0] : nil has_exist_condition = parse_content.split("\n")[0].match(/if[ ]+\w+/).present? exist_condition = parse_content.split("\n")[0].match(/if[ ]+#{::Regexp.escape(k)}(?=\.| |$)/) if has_exist_condition && exist_condition.nil? #if this block is for other variables, then not proccessing @parse_again_mode = false result else extra_cond = nil if exist_condition exist_condition = exist_condition[0] parse_content = parse_content[ parse_content.index(exist_condition) + exist_condition.length..-1] extra_cond = parse_content.match(/^\.count *(\!|\<|\>|\=)(\=|) *\d+/) if extra_cond extra_cond = extra_cond[0] exist_condition += extra_cond parse_content = parse_content[extra_cond.length..-1] exist_condition = eval("vv"+extra_cond) ? exist_condition : nil elsif vv.count == 0 exist_condition = nil end if exist_condition.nil? match_count = nil parse_content = "" result = "" end elsif match_count parse_content = parse_content[match_count.length..-1] end parse_content = parse_content.sub(/[ \t]+\z/m, '').sub(/\A(\r\n|\n)/, '') if include_key(parse_content,k) vv_count = vv.count if match_count vv_count = [vv_count, match_count.strip[1..-1].to_i].min end if inner result = (0...vv_count).map {|ii| replace_text_with_pattern(parse_content,false,i,ii,true) }.join("") else result = (0...vv_count).map {|ii| replace_text_with_pattern(parse_content,false,ii) }.join("") end elsif match_count || exist_condition count = 1 if match_count count = match_count.strip[1..-1].to_i end result = (0...count).map {|ii| parse_content }.join("") end @parse_again_mode = false result end end new_text = gsub_text_by_key_value(new_text,k,vv.to_s) 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) @blank_texts = [] if !@parse_again_mode text.gsub(/\n(\s+)[^\n]*(#{k}|#{k.classify})/m) {|ff| @blank_texts << $1.gsub(/(\r\n|\n)/,'')} end if k == 'display_field_code' puts nil puts "display_field_code: @parse_again_mode: #{@parse_again_mode}" print @blank_texts puts nil end i = 0 text = text.gsub(k + "s"){|ff| v.pluralize.gsub("\n","\n#{@blank_texts[i]}")} text = text.gsub(k ){|ff| v.gsub("\n","\n#{@blank_texts[i]}")} text = text.gsub(k.classify + "s"){|ff| v.classify.pluralize.gsub("\n","\n#{@blank_texts[i]}")} text = text.gsub(k.classify){|ff| v.classify.gsub("\n","\n#{@blank_texts[i]}")} end def get_all_gem_plugins extention_files = ["downloaded_extensions.rb","built_in_extensions.rb"] gem_plugins = extention_files.map{|f| (File.read(f).scan(/\n\s*gem\s*["'](.*)["']\s*,/).flatten rescue [])}.flatten end def check_plugin_exist gem_plugins = get_all_gem_plugins can_install = !gem_plugins.include?(params[:plugin_name]) can_install = (PersonalPluginField.find(params[:id]).module_name == params[:plugin_name] rescue false) if !can_install render :json => {:can_install => can_install } end def add_plugin(extention_file,plugin_name) txt = File.read(extention_file) rescue nil if txt.nil? File.open(extention_file,'w+'){|f| f.write("")} txt = "" end txt_scan = txt.scan(/^[\n]*gem\s*["']#{plugin_name}["'].*\n/) if txt_scan.count != 1 delete_plugin(extention_file,plugin_name) txt = File.read(extention_file) rescue "" txt = txt + "\ngem \"#{plugin_name}\", path: \"#{Rails.root}/tmp/#{plugin_name}\"\n" File.open(extention_file,'w+') do |f| f.write(txt) end end end def delete_plugin(extention_file,plugin_name) txt = File.read(extention_file) rescue nil return if txt.nil? txt_change = txt.gsub(/^[\s#]*gem\s*["']#{plugin_name}["'].*(\n|$)/m,'') if txt_change != txt File.open(extention_file,'w+') do |f| f.write(txt_change) end end end def check_modal_name primary_modal_names = PersonalPluginField.where(:id.ne=>params[:id]).pluck(:primary_modal_name) related_modal_names = PersonalPluginField.where(:id.ne=>params[:id]).pluck(:related_modal_name).flatten.uniq other_modal_names = primary_modal_names + related_modal_names personal_plugin_field = PersonalPluginField.where(:id=>params[:id]).first all_modal_names = PersonalPluginField.get_modal_names_cache if personal_plugin_field.present? except_modals = Dir.glob("tmp/#{personal_plugin_field.module_name}/app/models/*.rb").map{|f| fn = File.basename(f) fn.slice(0,fn.length - 3) } all_modal_names = all_modal_names - except_modals end all_modal_names = all_modal_names + other_modal_names all_modal_names = all_modal_names.uniq self_modal_names = params[:modal_names] invalid_modal_names = self_modal_names.select{|n| all_modal_names.include?(n)} if invalid_modal_names.count != 0 render :json => {:success=>false,:invalid_modal_names=>invalid_modal_names} else render :json => {:success=>true} end 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].sort_by{|k, h| h[:order].to_i}.map{|v| v[1]} 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.sort_by{|k, h| h[:order].to_i}.map{|v| v[1]}} else personal_plugin_field_params[:related_modal_fields] = [] end return personal_plugin_field_params end def set_personal_plugin_field PersonalPluginField.get_modal_names_cache 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 def bundle_install Bundler.with_clean_env { system("cd #{Rails.root} && bundle install") } %x(kill -s USR2 `cat tmp/pids/unicorn.pid`) sleep 2 end end