personal_plugin_generator/app/controllers/admin/personal_plugin_fields_cont...

967 lines
42 KiB
Ruby

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" +
" <div class=\"quick-edit\">\n"+
" <ul class=\"nav nav-pills hide\">\n"+
" <li><%= link_to t('edit'), edit_admin_#{plugin_template}_path(#{plugin_template},:page => params[:page]) %></li>\n"+
" <li><%= link_to t(:delete_), admin_#{plugin_template}_path(id: #{plugin_template}.id, :page => params[:page]), method: :delete, data: { confirm: 'Are you sure?' } %></li>\n"+
" </ul>\n"+
" </div>\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" +
" <div class=\"quick-edit\">\n"+
" <ul class=\"nav nav-pills hide\">\n"+
" <li><%= link_to t('edit'), edit_admin_#{plugin_template}_path(#{plugin_template},:page => params[:page]) %></li>\n"+
" <li><%= link_to t(:delete_), admin_#{plugin_template}_path(id: #{plugin_template}.id, :page => params[:page]), method: :delete, data: { confirm: 'Are you sure?' } %></li>\n"+
" </ul>\n"+
" </div>\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}\"<li><a href='\#{url}'' target='_blank'>\#{title}</li>\"",
"#{@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}\"<li><a href='\#{url}'' target='_blank'>\#{title}</li>\"",
"#{@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 : \"<a href='\#{path}'>\#{m.name}</a>\")",
"#{@blank_text}}",
"#{@blank_text}join_text = (text_only rescue false) ? \",\" : \"<br>\"",
"#{@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 : \"<a href='\#{link}' target='_blank' title='\#{tmp_title}'>\#{tmp_title}</a>\"\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|
"<span><%=t(\"#{personal_plugin_template}.extend_translate.#{f}_#{field_type}\")%></span>" +
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("<br>").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("<br>")
@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|
"<span><%=t(\"#{personal_plugin_template}.extend_translate.#{f}_#{field_type}\")%></span>" +
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