Add must_verify_email feature.

This commit is contained in:
邱博亞 2024-09-21 22:03:51 +08:00
parent 6f96111d98
commit 591a7ff11f
10 changed files with 215 additions and 100 deletions

View File

@ -198,6 +198,7 @@ class Admin::AsksController < OrbitAdminController
.any_in(:situation => filter2("situation"))
end
@askquestions = @askquestions.where(:category_id=>category_id) if category_id
@askquestions = @askquestions.where(:is_hidden.ne=> true)
# 分頁
@askquestions = search_data(@askquestions,[:title]).page(params[:page]).per(10)
if request.xhr?

View File

@ -6,7 +6,7 @@ class AsksController < ApplicationController
helper ActionView::Helpers::UrlHelper
include ActionController::RequestForgeryProtection
include RuCaptcha::ViewHelpers
FrontendMethods = ["thank", "sorry"]
FrontendMethods = ["thank", "sorry", "see_email"]
def widget
subpart = OrbitHelper.get_current_widget
case subpart.widget_type
@ -46,7 +46,7 @@ class AsksController < ApplicationController
request = OrbitHelper.request
csrf_value = OrbitHelper.request.session[:_csrf_token] || SecureRandom.base64(32)
token_tag = hidden_field_tag('authenticity_token',csrf_value)
switch_form = cal_switch_form(ask_settings,categories,token_tag,referer_url)
switch_form = cal_switch_form(ask_settings,categories,token_tag,referer_url, OrbitHelper.params[:id])
email_regex = @default_ask_setting.get_email_regex(true)
{
'fields' => all_fields,
@ -120,7 +120,7 @@ class AsksController < ApplicationController
when 'sorry'
render :sorry and return {}
end
referer_url = OrbitHelper.request.fullpath
referer_url = OrbitHelper.request.path
if @params['item'].to_s.empty?
get_layout_type
else
@ -156,7 +156,7 @@ class AsksController < ApplicationController
end
csrf_value = OrbitHelper.request.session[:_csrf_token] || SecureRandom.base64(32)
token_tag = hidden_field_tag('authenticity_token',csrf_value)
switch_form = cal_switch_form(ask_settings,categories,token_tag,referer_url)
switch_form = cal_switch_form(ask_settings,categories,token_tag,referer_url, params[:id])
tags = module_app.tags
ask_question = AskQuestion.new(id: nil)
email_regex = @default_ask_setting.get_email_regex(true)
@ -194,8 +194,16 @@ class AsksController < ApplicationController
if !params[:referer_url].blank? && !params[:referer_url].to_s.start_with?("/")
render :file => "#{Rails.root}/app/views/errors/403.html", :layout => false, :status => 403 and return
end
@ask_question = AskQuestion.new(:ip=>request.remote_ip)
temp_params = create_params
if temp_params[:id].present?
@ask_question = AskQuestion.where(id: temp_params[:id]).first
if @ask_question.nil?
render_404 and return
end
else
@ask_question = AskQuestion.new(:ip=>request.remote_ip)
end
new_record = @ask_question.new_record?
all_to_save = []
ask_setting = AskCategorySetting.enabled.where(category_id: params['ask_question']['category_id']).first
override_sort_number = nil
@ -208,13 +216,24 @@ class AsksController < ApplicationController
ask_setting = AskSetting.create() if ask_setting.nil?
end
@ask_setting = ask_setting
check_fields = ask_setting.default_setting.select{|k,v| v}.keys & ask_setting.default_setting_required.select{|k,v| v}.keys - AskSetting::No_required
flag = true
check_fields.each do |f|
next if f == 'ask_category_id' || f == 'recaptcha'
if temp_params[f].blank?
flag = false
break
@must_verify_email = ask_setting.must_verify_email && new_record
if @must_verify_email
only_email = true
@ask_question.is_hidden = true
else
only_email = false
check_fields = ask_setting.default_setting.select{|k,v| v}.keys & ask_setting.default_setting_required.select{|k,v| v}.keys - AskSetting::No_required
unless new_record
@ask_question.is_hidden = false
check_fields.delete('mail')
end
flag = true
check_fields.each do |f|
next if f == 'ask_category_id' || f == 'recaptcha'
if temp_params[f].blank?
flag = false
break
end
end
end
custom_values = temp_params[:custom_values]
@ -247,22 +266,24 @@ class AsksController < ApplicationController
end
end
end
if !flag
if !flag && !only_email
redirect_to "#{params[:referer_url]}?method=sorry" and return
end
email_regex = ask_setting.get_email_regex
ask_setting.custom_fields.select{|k,v| v['type']=='file' || v['type']=='image'}.each do |k,v|
file = custom_values[k]
if !file.blank?
if v['type']=='image'
all_to_save += [[k,AskImage.new(file: file,ask_question_id: @ask_question.id)]]
else
all_to_save += [[k,AskFile.new(file: file,ask_question_id: @ask_question.id)]]
unless only_email
ask_setting.custom_fields.select{|k,v| v['type']=='file' || v['type']=='image'}.each do |k,v|
file = custom_values[k]
if !file.blank?
if v['type']=='image'
all_to_save += [[k,AskImage.new(file: file,ask_question_id: @ask_question.id)]]
else
all_to_save += [[k,AskFile.new(file: file,ask_question_id: @ask_question.id)]]
end
end
end
end
flag = !ask_setting.default_setting['recaptcha'] || gotcha_valid?
if flag
if flag && !only_email
all_to_save.each do |to_save|
flag = flag && to_save[1].save
custom_values[to_save[0]] = [custom_values[to_save[0]].original_filename ,to_save[1].file.url]
@ -277,13 +298,24 @@ class AsksController < ApplicationController
})
end
@ask_question.update_attributes(temp_params)
if ask_setting.validate_enable && AskSafeEmail.where(:email=> @ask_question.mail).count == 0
build_verification_email(@ask_question)
if @must_verify_email
referer_url = "#{params[:referer_url]}?id=#{@ask_question.id}"
else
referer_url = nil
end
if (ask_setting.validate_enable || @must_verify_email) && AskSafeEmail.where(:email=> @ask_question.mail).count == 0
build_verification_email(@ask_question, referer_url)
elsif @must_verify_email
redirect_to referer_url and return
else
@ask_question.update(:situation => AskTicketStatus::DefaultKeys[1])
build_email(@ask_question)
end
redirect_to "#{params[:referer_url]}?method=thank"
if @must_verify_email
redirect_to "#{params[:referer_url]}?method=see_email"
else
redirect_to "#{params[:referer_url]}?method=thank"
end
else
redirect_to "#{params[:referer_url]}?method=sorry"
end
@ -300,6 +332,9 @@ class AsksController < ApplicationController
{}
end
def see_email
end
def render_404
render :file => "#{Rails.root}/app/views/errors/404", :layout => false, :status => :not_found, :formats => [:html]
end
@ -318,7 +353,7 @@ class AsksController < ApplicationController
end
end
def build_verification_email(email_er)
def build_verification_email(email_er, referer_url)
email = Email.new
email.save
email_er.email_id = email.id
@ -336,6 +371,12 @@ class AsksController < ApplicationController
end
verify_url = "#{host_url}/#{I18n.locale}/xhr/asks/verify_email/#{email_er.id}"
verify_link = "<a title=\"#{t('ask.verify_link')}\" href=\"#{verify_url}\" target=\"_blank\">#{verify_url}</a>"
if referer_url
referer_url = host_url + referer_url
referer_link = "<a title=\"#{I18n.t('ask.go_to_form')}\" href=\"#{referer_url}\" target=\"_blank\">#{referer_url}</a>"
else
referer_link = nil
end
mail_subject = mail_from+": #{t('ask.email_verification_notification')}"
email_er.email.update_attributes(
:mail_lang=> site.default_locale,
@ -348,7 +389,8 @@ class AsksController < ApplicationController
:template_data=>{
"validation_email_content" => @ask_setting.validation_email_content,
"verify_link" => verify_link,
"site_host" => host_url,
"referer_link" => referer_link,
"site_host" => host_url
},
:mail_reply_to => (manager_emails.empty? ? nil : manager_emails)
)
@ -454,91 +496,121 @@ class AsksController < ApplicationController
all_fields = []
set_input_name_for_ask("ask_question")
has_ask_category_id = false
disp_fields_infos.each do |field, info|
if field.start_with?("default@")
k = is_cat_record ? field : field[8..-1]
v = ask_setting.custom_fields[k]
if v
field_name = info['trans']
if field_name.present?
id = "#{get_input_name_for_ask}[custom_values][#{k}]"
all_fields << {'field'=>field,'label'=>ask_label(id, field_name, v['required']),'content'=>show_on_front(k,v)}
end
end
elsif field.start_with?("custom@") && is_cat_record
if field.include?(tmp_ask_cat_id)
k = field[8+tmp_ask_cat_id.length..-1]
if ask_setting.must_verify_email && @ask_question.nil?
field = "mail"
field_name = "ask_question[#{field}]"
id = field_name
required = true
placeholder = @default_ask_setting.prompt_word(field)
f1 = {'style_html'=>''}
f1['content'] = text_field_tag(field_name,nil,data: (required ? {"fv-validation" => "required;check_email;", "fv-messages" => "必填欄位;Email不正確;"} : {}),required: required,placeholder: placeholder)
f1['field'] = field
f1['label'] = ask_label(id, @default_ask_setting.field_name("#{field}"),required.to_s)
all_fields << f1
field = "recaptcha"
id = "ask_rucaptcha"
f1 = {'style_html'=>''}
f1['content'] = "#{gotcha_error(:espeak=>true)}#{gotcha(id: id)}"
f1['field'] = field
f1['label'] = ask_label(id, @default_ask_setting.field_name("#{field}"),required.to_s)
all_fields << f1
all_fields << {'field'=>'must_verify_email','style_html'=>'display: block; text-align: center;','label'=>'','content'=> I18n.t('ask.must_verify_email')}
else
disp_fields_infos.each do |field, info|
if field.start_with?("default@")
k = is_cat_record ? field : field[8..-1]
v = ask_setting.custom_fields[k]
if v
field_name = info['trans']
if field_name.present?
id = "#{get_input_name_for_ask}[custom_values][#{k}]"
all_fields << {'field'=>field,'label'=>ask_label(id, v['field'][I18n.locale],v['required']),'content'=>show_on_front(k,v)}
all_fields << {'field'=>field,'label'=>ask_label(id, field_name, v['required']),'content'=>show_on_front(k,v)}
end
end
end
else
if field == 'ask_category_id'
has_ask_category_id = true
if show_categories || ask_setting.default_setting[field]
if categories.count > 1
id = "ask_question[category_id]"
all_fields << {'field'=>field,'style_html'=>'','label'=>ask_label(id, @default_ask_setting.field_name("ask_category_id"),'true'),'content'=>select_tag('ask_question[category_id]', options_for_select(categories.collect{|t| [ t.title, t.id ]}))}
else
all_fields << {'field'=>field,'style_html'=>'','label'=>ask_label(nil, @default_ask_setting.field_name("ask_category_id"),'true'),'content'=>"<span>#{(categories[0].title rescue '')}</span>"+hidden_field_tag('ask_question[category_id]', (categories[0].id.to_s rescue ''))}
elsif field.start_with?("custom@") && is_cat_record
if field.include?(tmp_ask_cat_id)
k = field[8+tmp_ask_cat_id.length..-1]
v = ask_setting.custom_fields[k]
if v
field_name = info['trans']
if field_name.present?
id = "#{get_input_name_for_ask}[custom_values][#{k}]"
all_fields << {'field'=>field,'label'=>ask_label(id, v['field'][I18n.locale],v['required']),'content'=>show_on_front(k,v)}
end
end
else
all_fields << {'field'=>field,'style_html'=>'display: none;','label'=>'','content'=>hidden_field_tag('ask_question[category_id]', (categories[0].id.to_s rescue ''))}
end
else
if ask_setting.default_setting[field] || field == "usage_rule"
required = ask_setting.is_required(field)
f1 = {'style_html'=>''}
field_name = "ask_question[#{field}]"
placeholder = @default_ask_setting.prompt_word(field)
id = field_name
case field
when 'title'
f1['content'] = text_field_tag(field_name,nil,placeholder: placeholder,required: required)
when 'name'
f1['content'] = text_field_tag(field_name,nil,data: (required ? {"fv-validation" => "required;", "fv-messages" => "必填欄位;"} : {}),required: required,placeholder: placeholder)
when 'sex'
id += "_male"
f1['content'] = "<label class=\"radio-inline\">
#{radio_button_tag(field_name,'male', false, {required: required})}#{I18n.t('users.male')}
</label>
<label class=\"radio-inline\">
#{radio_button_tag(field_name,'female', false, {required: required})}#{I18n.t('users.female')}
</label>"
when 'mail'
f1['content'] = text_field_tag(field_name,nil,data: (required ? {"fv-validation" => "required;check_email;", "fv-messages" => "必填欄位;Email不正確;"} : {}),required: required,placeholder: placeholder)
when 'phone'
f1['content'] = text_field_tag(field_name,nil,placeholder: placeholder,required: required)
when 'appointment'
if @appointment_idx.nil?
@appointment_idx = 0
if field == 'ask_category_id'
has_ask_category_id = true
if show_categories || ask_setting.default_setting[field]
if categories.count > 1
id = "ask_question[category_id]"
all_fields << {'field'=>field,'style_html'=>'','label'=>ask_label(id, @default_ask_setting.field_name("ask_category_id"),'true'),'content'=>select_tag('ask_question[category_id]', options_for_select(categories.collect{|t| [ t.title, t.id ]}))}
else
@appointment_idx += 1
all_fields << {'field'=>field,'style_html'=>'','label'=>ask_label(nil, @default_ask_setting.field_name("ask_category_id"),'true'),'content'=>"<span>#{(categories[0].title rescue '')}</span>"+hidden_field_tag('ask_question[category_id]', (categories[0].id.to_s rescue ''))}
end
id = "ask_question_appointment_#{@appointment_idx}"
f1['content'] = "<div class=\"default_picker\">#{text_field_tag(field_name,nil,placeholder: placeholder,data: {format: 'yyyy/MM/dd hh:mm'},required: required, id: id)}</div>"
when 'recaptcha'
id = "ask_rucaptcha"
f1['content'] = "#{gotcha_error(:espeak=>true)}#{gotcha(id: id)}"
when 'usage_rule'
next if ask_setting.usage_rule.blank?
f1['content'] = ask_setting.usage_rule
when 'agree_show'
f1['content'] = check_box_tag(field_name, "1", false, {required: required})
when 'agree_usage'
f1['content'] = check_box_tag(field_name, "1", false, {required: required})
else
all_fields << {'field'=>field,'style_html'=>'display: none;','label'=>'','content'=>hidden_field_tag('ask_question[category_id]', (categories[0].id.to_s rescue ''))}
end
else
if ask_setting.default_setting[field] || field == "usage_rule"
required = ask_setting.is_required(field)
f1 = {'style_html'=>''}
field_name = "ask_question[#{field}]"
placeholder = @default_ask_setting.prompt_word(field)
id = field_name
case field
when 'title'
f1['content'] = text_field_tag(field_name,nil,placeholder: placeholder,required: required)
when 'name'
f1['content'] = text_field_tag(field_name,nil,data: (required ? {"fv-validation" => "required;", "fv-messages" => "必填欄位;"} : {}),required: required,placeholder: placeholder)
when 'sex'
id += "_male"
f1['content'] = "<label class=\"radio-inline\">
#{radio_button_tag(field_name,'male', false, {required: required})}#{I18n.t('users.male')}
</label>
<label class=\"radio-inline\">
#{radio_button_tag(field_name,'female', false, {required: required})}#{I18n.t('users.female')}
</label>"
when 'mail'
if @ask_question
f1['content'] = @ask_question.mail
else
f1['content'] = text_field_tag(field_name,nil,data: (required ? {"fv-validation" => "required;check_email;", "fv-messages" => "必填欄位;Email不正確;"} : {}),required: required,placeholder: placeholder)
end
when 'phone'
f1['content'] = text_field_tag(field_name,nil,placeholder: placeholder,required: required)
when 'appointment'
if @appointment_idx.nil?
@appointment_idx = 0
else
@appointment_idx += 1
end
id = "ask_question_appointment_#{@appointment_idx}"
f1['content'] = "<div class=\"default_picker\">#{text_field_tag(field_name,nil,placeholder: placeholder,data: {format: 'yyyy/MM/dd hh:mm'},required: required, id: id)}</div>"
when 'recaptcha'
id = "ask_rucaptcha"
f1['content'] = "#{gotcha_error(:espeak=>true)}#{gotcha(id: id)}"
when 'usage_rule'
next if ask_setting.usage_rule.blank?
f1['content'] = ask_setting.usage_rule
when 'agree_show'
f1['content'] = check_box_tag(field_name, "1", false, {required: required})
when 'agree_usage'
f1['content'] = check_box_tag(field_name, "1", false, {required: required})
end
f1['field'] = field
f1['label'] = ask_label(id, @default_ask_setting.field_name("#{field}"),required.to_s)
all_fields << f1
end
f1['field'] = field
f1['label'] = ask_label(id, @default_ask_setting.field_name("#{field}"),required.to_s)
all_fields << f1
end
end
end
if @ask_question
all_fields << {'field'=>'ask_question_id','style_html'=>'display: none;','label'=>'','content'=>hidden_field_tag('ask_question[id]', @ask_question.id)}
end
end
unless has_ask_category_id
all_fields << {'field'=>'ask_category_id','style_html'=>'display: none;','label'=>'','content'=>hidden_field_tag('ask_question[category_id]', category_id)}
@ -623,9 +695,24 @@ class AsksController < ApplicationController
})
</script>"
end
def cal_switch_form(ask_settings,categories,token_tag,referer_url)
def cal_switch_form(ask_settings,categories,token_tag,referer_url, ask_question_id)
switch_form = ''
default_idx = 0
if ask_question_id.present?
@ask_question = AskQuestion.where(:id=> ask_question_id).first
if @ask_question && !(@ask_question.is_hidden)
@ask_question = nil
end
if @ask_question
AskSafeEmail.create(:email=> @ask_question.mail) if AskSafeEmail.where(:email=> @ask_question.mail).count == 0
ask_settings = AskCategorySetting.enabled.where(:category_id=> @ask_question.category_id).to_a
if ask_settings.blank?
ask_settings = [AskSetting.first]
end
end
else
@ask_question = nil
end
if categories.count != 0
default_idx = ask_settings[1..-1].to_a.map{|a| a.category_id.to_s}.index(categories[0].id.to_s)
default_idx = default_idx.nil? ? 0 : default_idx + 1

View File

@ -146,6 +146,7 @@ class AskCategorySetting
field :email_regex_enable, type: Boolean, default: false
field :email_regex, type: String, default: '\A[^@\s]+@([^@.\s]+\.)+[^@.\s]+\z'
field :validate_enable, type: Boolean, default: false
field :must_verify_email, type: Boolean, default: false
field :validation_email_content, type: String, localize: true
field :tmp_sort_number, type: Hash, default: {} # For Frontend

View File

@ -27,11 +27,14 @@ class AskQuestion
field :custom_values, type: Hash, default: {}
field :agree_show, type: Boolean, default: false
field :agree_usage, type: Boolean, default: false
field :is_hidden, type: Boolean
field :review_time, type: DateTime
belongs_to :reviewer, class_name: "MemberProfile", foreign_key: :reviewer_id
has_many :ask_status_histories
index({situation: 1, identity: 1, is_hidden: -1}, { unique: false, background: true })
attr_accessor :release_comment, :release_file, :user
before_create do

View File

@ -94,6 +94,7 @@ class AskSetting
field :email_regex_enable, type: Boolean, default: false
field :email_regex, type: String, default: '\A[^@\s]+@([^@.\s]+\.)+[^@.\s]+\z'
field :validate_enable, type: Boolean, default: false
field :must_verify_email, type: Boolean, default: false
field :validation_email_content, type: String, localize: true
field :tmp_sort_number, type: Hash, default: {}

View File

@ -180,7 +180,8 @@
<label for="ask_email_regex"><%= t("ask.validation_email_content") %>:</label>
</div>
<div class="controls">
<label id="<%= "#{f.object_name}_validate_enable" %>"><%= f.check_box :validate_enable %><%= t('ask.enable') %></label>
<label class="pull-left" id="<%= "#{f.object_name}_validate_enable" %>"><%= f.check_box :validate_enable %><%= t('ask.enable') %></label>
<label id="<%= "#{f.object_name}_must_verify_email" %>"><%= f.check_box :must_verify_email %><%= t('ask.must_verify_email') %></label>
<div style="clear: both;"></div>
<%= multiple_lang_tag_for_ask(
nil,
@ -220,7 +221,8 @@
<label for="ask_email_regex"><%= t("ask.validation_email_content") %>:</label>
</div>
<div class="controls">
<label id="<%= "#{f.object_name}_validate_enable" %>"><%= f.check_box :validate_enable %><%= t('ask.enable') %></label>
<label class="pull-left" id="<%= "#{f.object_name}_validate_enable" %>"><%= f.check_box :validate_enable %><%= t('ask.enable') %></label>
<label id="<%= "#{f.object_name}_must_verify_email" %>"><%= f.check_box :must_verify_email %><%= t('ask.must_verify_email') %></label>
<%= multiple_lang_tag_for_ask(
nil,
'text_area',

View File

@ -8,8 +8,13 @@
<%= @data['validation_email_content'].to_s.gsub(/[(\n)(\r)]/, "\n" => "<br/>", "\r" => "" ).html_safe %>
</p>
<br />
<%= @data['verify_link'].html_safe %>
<br />
<% if @data['referer_link'] %>
<%= @data['referer_link'].html_safe %>
<br />
<% else %>
<%= @data['verify_link'].html_safe %>
<br />
<% end %>
<p><%= t('ask.email_automation_hint') %></p>
</body>
</html>

View File

@ -0,0 +1,9 @@
<link href="/assets/ask/ask.css" media="screen" rel="stylesheet">
<div class="form-horizontal">
<h2>
<%= t('ask.see_email') %>
<div class="form-actions">
<a class="btn" href="<%= OrbitHelper.request.path_info %>"><%=t('ask.go_back')%></a>
</div>
</h2>
</div>

View File

@ -137,6 +137,9 @@ en:
remark: Remark
attachment: Attachment
updated_at: Updated at
must_verify_email: The form can only be filled in after email verification.
go_to_form: Go to Form
see_email: "Please check your email, so you can fill out the form."
mongoid:
attributes:

View File

@ -147,6 +147,9 @@ zh_tw:
remark: 備註
attachment: 附件
updated_at: 更新時間
must_verify_email: Email驗證後才可開始填寫
go_to_form: 前往表單
see_email: "請確認email驗證信以開始填寫表單。"
mongoid:
attributes: