patch_file/updatefiles/pages_controller.rb

738 lines
26 KiB
Ruby

# pass the layout=false for not rendering the layouts and also can specify the methods to in the backend controller.
# data-layout-content="arrayname" in layouts can be used to render data in the array
require 'zhconv'
require "uri"
class PagesController < ApplicationController
before_action :get_key
layout :get_layout
include PagesHelper
before_filter :check_frontend_open, :only => [:home,:show]
before_filter :check_authorization, :except => [:home,:show]
before_filter :set_edit_mode
prepend_view_path "app/templates"
def index
@pages = Page.all
# render json: @pages
end
def edit_view
@manifest = @key
@dataApi = "edit"
view = get_view
if File.exists?(view)
render view
end
end
def home
@manifest = @key
page = Page.root
Thread.new do
impressionist(page)
end
page.inc(view_count: 1)
params[:is_frontend_view] = "true"
OrbitHelper.set_params params,current_user
OrbitHelper.set_site_locale locale
OrbitHelper.set_request_object request
OrbitHelper.render_meta_tags []
render :html => render_final_page("home",page,true).html_safe
end
def show
display_type = ""
path = request.path.split('/')
params[:is_frontend_view] = "true"
if path.size <= 2
redirect_to root_path
else
if path.last.include? '-'
params[:page_id] = path[-2]
s = CGI.unescape(path[-1])
s.encode!('UTF-8')
params[:slug] = s
uid = path[-1].split("-").last
uid = uid.split("?").first
if uid.include?(".")
render :file => "#{Rails.root}/app/views/errors/404.html", :layout => false, :status => :not_found
return
end
params[:uid] = uid
params[:target_action] = params[:method] || "show"
display_type = "show"
else
params[:page_id] = path[-1]
params[:slug] = nil
params[:uid] = nil
params[:target_action] = params[:method] || "index"
display_type = "index"
OrbitHelper.set_page_number params[:page_no].to_i || 1
end
page = Page.find_by_param(params[:page_id])
if !page.nil?
if !page.user_can_access?(current_user)
render :file => "#{Rails.root}/app/views/errors/403.html", :layout => false, :status => 403
return
end
if !page.enabled_for_mobile && !$mobile.blank?
render :file => "#{Rails.root}/app/views/errors/404.html", :layout => false, :status => :not_found
return
end
if page.enabled_for.include? I18n.locale.to_s
if page.page_type == "link"
begin
refer_url = URI.parse(page.external_url).to_s
rescue URI::InvalidURIError
refer_url = root_url
end
redirect_to refer_url
return
end
module_app = page.module.downcase.pluralize
params[:target_controller] = "#{module_app}"
if display_type == "index"
params[:layout_type] = params[:method] || page.layout || "index"
end
params[:url] = page.url
categories = []
if page.module == "member"
if page.categories.first == "all"
categories = ["all"]
else
page.categories.each do |c|
category = Role.find(c) rescue nil
if !category.nil? && !category.disabled
categories << c
end
end
end
else
page.categories.each do |c|
category = Category.find(c) rescue nil
if !category.nil? && !category.disable
categories << c
end
end
categories = ["all"] if categories.blank?
end
@manifest = @key
OrbitHelper.set_params params,current_user
OrbitHelper.set_request_object request
OrbitHelper.set_site_locale locale
OrbitHelper.set_this_module_app module_app.singularize
OrbitHelper.set_page_categories categories || ["all"]
OrbitHelper.set_page_tags page.tags || []
OrbitHelper.set_page_role_status page.role_status || []
OrbitHelper.set_member_sort_position page.member_sort_position
OrbitHelper.set_page_data_count page.data_count
if params[:layout].kind_of?(String)
layout = to_bool(params[:layout])
else
layout = true
end
Thread.new do
impressionist(page)
end
page.inc(view_count: 1)
render :html => render_final_page("#{module_app}/#{params[:target_action]}",page,layout).html_safe
else
if Site.first.enable_redirect_index
redirect_to root_url
else
render :file => "#{Rails.root}/app/views/errors/411.html", :layout => false, :status => :not_found
end
end
else
render :file => "#{Rails.root}/app/views/errors/404.html", :layout => false, :status => :not_found
end
end
end
def update_child_pages_url(page)
page.child_page.each do |cp|
if !cp.child_page.blank?
update_child_pages_url(cp)
else
cp.url = page.url + "/#{cp.page_id}"
cp.save
end
end
end
def update_item_position
@page = Page.find(params[:id])
new_parent_page = Page.find(params[:parent_id])
old_parent_page_id = @page.parent_page_id
@page.parent_page_id = new_parent_page.id
if new_parent_page.id != old_parent_page_id
url = (new_parent_page.url == "/" ? "" : new_parent_page.url)
@page.url = url + "/#{@page.page_id}"
if !@page.child_page.blank?
update_child_pages_url(@page)
end
end
@page.save
params["children_ids"].each_with_index do |child,i|
page = Page.find(child)
page.number = i
page.save
end
if new_parent_page.id != old_parent_page_id
old_parent_page = Page.find(old_parent_page_id)
# old_parent_page.child_page.each_with_index do |page,i|
# page.number = i
# page.save
# end
params["parent_children_ids"] = params["parent_children_ids"] || []
params["parent_children_ids"].each_with_index do |child, i|
page = Page.find(child)
page.number = i
page.save
end
end
render :json => {"success"=>true}.to_json
end
def preview
render render_final_page
end
def destroy
page = Page.find(params[:id])
# @parent_pages = page.parent_pages_without_root
@pageid = page.id.to_s
page.destroy
respond_to do |format|
format.js
end
end
def import_widgets
page = Page.find(params[:id]) rescue nil
page.page_parts.destroy_all
if !page.nil?
page.parent_page.page_parts.each do |pp|
new_pp = pp.clone
new_pp.page_id = page.id
pp.sub_parts.each do |sp|
new_sp = sp.clone
new_pp.sub_parts << new_sp
end
new_pp.save
page.page_parts << new_pp
end
page.save
end
render :json => {"success" => true}.to_json
end
def get_member_attributes
@page_id = params[:page_id]
@type = params[:type]
@selected_attribs = []
if @type == "index"
@selected_attribs = Page.find(@page_id).custom_array_field
@selected_attribs = [
{"key"=>"name", "type"=>"profile","sort_order"=>2,"link_to_show"=>true, "human_readable" => I18n.t("users.name")},
{"key"=>"email", "type"=>"profile", "human_readable" => I18n.t("users.email")},
{"key"=>"office_tel", "type"=>"profile", "human_readable" => I18n.t("users.office_tel")}
] if @selected_attribs.blank?
elsif @type == "show"
@selected_attribs = Page.find(@page_id).custom_array_field_for_show
if @selected_attribs.blank?
@selected_attribs = [
{"key"=>"name", "type"=>"profile","sort_order"=>2,"link_to_show"=>true, "human_readable" => I18n.t("users.name")},
{"key"=>"email", "type"=>"profile", "human_readable" => I18n.t("users.email")},
{"key"=>"office_tel", "type"=>"profile", "human_readable" => I18n.t("users.office_tel")}
]
infos = MemberInfo.order('created_at DESC')
infos.each do |info|
info.member_profile_fields.each do |member_profile_field|
@selected_attribs << {"id"=> member_profile_field.id.to_s, "key"=> member_profile_field.key, "type"=>"custom"} if !member_profile_field.to_show.blank?
end
end
Role.where(:disabled => false).each do |role|
role.attribute_fields.each do |attribute_field|
@selected_attribs << {"id"=> attribute_field.id.to_s, "key"=> attribute_field.key, "type"=>"role", "role_key" => role.key}# if !attribute_field.to_show.blank?
end
end
end
end
personal_attribs = [
{"key" => "first_name", "human_readable" => I18n.t("users.first_name")},
{"key" => "last_name", "human_readable" => I18n.t("users.last_name")},
{"key" => "name", "human_readable" => I18n.t("users.name")},
{"key" => "sex", "human_readable" => I18n.t("users.sex")},
{"key" => "office_tel", "human_readable" => I18n.t("users.office_tel")},
{"key" => "mobile_no", "human_readable" => I18n.t("users.mobile_no")},
{"key" => "fax", "human_readable" => I18n.t("users.fax")},
{"key" => "member_tags", "human_readable" => I18n.t("users.member_tags")},
{"key" => "birthday", "human_readable" => I18n.t("users.birthday")},
{"key" => "address", "human_readable" => I18n.t("users.address")},
{"key" => "personal_website", "human_readable" => I18n.t("users.personal_website")},
{"key" => "autobiography", "human_readable" => I18n.t("users.autobiography")},
{"key" => "email", "human_readable" => I18n.t("users.email")}
]
custom_attribs = MemberProfileField.all.asc(:created_at).collect do |mpf|
{"key" => mpf.key, "human_readable" => mpf.title, "id" => mpf.id.to_s}
end
role_attribs = []
ra = AttributeField.all.asc(:created_at).group_by(&:role)
keys = ra.keys
keys.each do |r|
next if r.nil?
t = {"role" => r.title, "role_key" => r.key, "attributes" => []}
ra[r].each do |af|
t["attributes"] << {"key" => af.key, "human_readable" => af.title, "id" => af.id.to_s}
end
role_attribs << t
end
@attribs = {
"profile" => personal_attribs,
"custom" => custom_attribs,
"role" => role_attribs,
"types" =>[
{"key" => "profile", "human_readable" => "Profile"},
{"key" => "custom", "human_readable" => "Custom"},
{"key" => "role", "human_readable" => "Role"}
]
}
render :partial => "member_frontend_field"
end
def save_member_frontend_fields
fields = params["fields"]
array = []
fields.each do |field|
array << field.last
end
page = Page.find(params[:page_id])
if params[:type] == "index"
page.custom_array_field = array
elsif params[:type] == "show"
page.custom_array_field_for_show = array
end
page.save
render :json => {"success" => true}.to_json
end
def get_categories
module_app = ModuleApp.find_by_key(params[:module]);
if module_app.key.eql?("member")
roles = Role.order_by(:_id=>'ASC').all.collect do |role|
{
"title" => role.title,
"id" => role.id.to_s,
"status" => RoleStatus.where(:role=>role).collect do |status|
{
"title" => status.title,
"id" => status.id.to_s
}
end
}
end
else
if !module_app.key.eql?("page_content")
categories = module_app.categories.enabled.collect do |cat|
{
"title" => cat.title,
"id" => cat.id.to_s
}
end
tags = module_app.tags.collect do |t|
{
"name" => t.name,
"id" => t.id.to_s
}
end
else
categories = []
tags = []
end
end
roles = roles.nil? ? [] : roles
categories = categories.nil? ? [] : categories
tags = tags.nil? ? [] : tags
if module_app.data_count.nil?
render :json => {"categories" => categories, "tags" => tags,"roles" => roles,"layouts" => (get_layouts module_app.key),"data_count" => {"present"=>false}, "locale" => I18n.locale.to_s}.to_json
else
render :json => {"categories" => categories, "tags" => tags,"roles" => roles,"layouts" => (get_layouts module_app.key),"data_count" => {"present"=>true,"start"=>module_app.data_count.begin, "end" => module_app.data_count.end}, "locale" => I18n.locale.to_s}.to_json
end
end
def new
@page = Page.new(
:enabled_for_mobile=>true,
:menu_enabled_for=>["en", "zh_tw"],
:enabled_for=>["en", "zh_tw"],
:enabled_for_sitemap=>["en", "zh_tw"]
)
@pages = Page.where(:page_id.ne => "" , :page_id.exists => true)
@modules = ModuleApp.all.frontend_enabled.order_by(:key=>'asc')
@al = [[t("access_level_none"),"none"], [t("access_level_users"),"users"]]
Role.all.each do |role|
@al << [role.title, role.id]
end
end
def edit
@page = Page.find(params[:id])
if params[:type] == "page"
@pages = Page.where(:page_id.ne => "" , :page_id.exists => true)
@modules = ModuleApp.all.frontend_enabled
@module_app = ModuleApp.find_by_key(@page.module) rescue nil
@categories = @module_app.categories.enabled rescue []
if @module_app.key.eql?("page_content")
@categories = []
end
@tags = @module_app.tags rescue []
if @module_app.key.eql?("member")
@roles = Role.order_by(:_id=>'ASC').all.collect do |role|
{
"title" => role.title,
"id" => role.id.to_s,
"status" => RoleStatus.where(:role=>role)
}
end
else
@roles = []
end
@layout_types = get_layouts @module_app.key
end
@al = [[t("access_level_none"),"none"], [t("access_level_users"),"users"]]
Role.all.each do |role|
@al << [role.title, role.id]
end
end
def update
@page = Page.find(params[:id])
@page.update_attributes(page_update_params)
@page.save
# @parent_pages = @page.parent_pages_without_root
respond_to do |format|
format.js
end
end
def create
params['page']['page_id'] = params['page']['page_id'].gsub('-','_')
@page = Page.new(page_params)
@page.save!
# @parent_pages = @page.parent_pages_without_root
respond_to do |format|
format.js
end
end
private
def get_layouts(module_app)
layout_types = []
f = File.join("#{Rails.root}/app/templates/#{@key}/modules/#{module_app}/info.json")
if File.exists?f
info = File.read(f)
hash = JSON.parse(info) rescue {}
frontends = hash["frontend"] || []
frontends.each do |frontend|
frontend["thumbnail"] = "/assets/#{module_app}/thumbs/#{frontend["thumbnail"]}"
layout_types << frontend
end
end
if layout_types.empty?
Dir.glob("#{Rails.root}/app/templates/#{@key}/modules/#{module_app}/*").each do |w|
next if File.ftype(w).eql?("directory")
w = File.basename(w, ".*")
w = File.basename(w, ".*")
if w[0,1] != "_" && w[0,1] != "s" && w != "info"
layout_types << w
end
end
end
layout_types
end
def render_final_page(original_view=get_view,page,layout)
final_html_for_render = ""
OrbitHelper.set_css_to_render_to_empty
if layout
parts = $mobile.blank? ? (page.page_parts rescue []) : (page.mobile_page_parts rescue [])
@part_partials = {}
parts.each do |part|
subparts = part.sub_parts.asc(:created_at)
partials = []
subparts.each do |subpart|
if subpart.kind == "module_widget"
OrbitHelper.set_current_widget subpart
OrbitHelper.set_widget_data_count subpart.data_count
OrbitHelper.set_widget_module_app subpart.module
OrbitHelper.set_widget_item_url subpart
OrbitHelper.render_meta_tags []
OrbitHelper.set_widget_title subpart.title
OrbitHelper.set_widget_categories subpart.categories || ["all"]
OrbitHelper.set_widget_tags subpart.tags || ["all"]
custom_value = subpart.custom_string_field || subpart.custom_array_field rescue nil
if !custom_value.nil?
OrbitHelper.set_widget_custom_value custom_value
end
if @editmode
partials << "<div class='editmode-ps' title='#{subpart.module}'> " + render_widget_for_frontend(subpart.module,subpart.widget_method,subpart.widget_type,subpart.id.to_s) + "<a href='/page_parts/edit_sub_part?page_id=#{page.id.to_s}&part_id=#{part.id.to_s}&sub_part_id=#{subpart.id.to_s}#{(!$mobile.blank? ? '&mobile_view=1' : '')}'> </a></div>"
else
# widget_html = Rails.cache.fetch("subpart_#{subpart.module}_#{subpart.id.to_s}_"+I18n.locale.to_s,{ race_condition_ttl: 2, expires_in: 5.minutes}) do
# render_widget_for_frontend(subpart.module,subpart.widget_method,subpart.widget_type,subpart.id.to_s)
# end
widget_html = render_widget_for_frontend(subpart.module,subpart.widget_method,subpart.widget_type,subpart.id.to_s)
partials << widget_html
end
elsif subpart.kind == "text"
if @editmode
partials << "<div class='editmode-ps' title='text'> " + subpart.content + "<a href='/page_parts/edit_sub_part?page_id=#{part.page_id.to_s}&part_id=#{part.id.to_s}&sub_part_id=#{subpart.id.to_s}#{(!$mobile.blank? ? '&mobile_view=1' : '')}'> </a></div>"
else
# change from px to em start
if subpart.content.include? "px"
@arrofindex = Array.new
@indexOfpx = subpart.content.index('px')
@arrofindex.push @indexOfpx
while @indexOfpx.nil? == false
@indexOfpx = subpart.content.index('px',@indexOfpx+1)
break if @indexOfpx.nil? == true
@arrofindex.push @indexOfpx
end
@arrofchangeString = Array.new
@arrofnewString = Array.new
@arrofindex.each do |indexPX|
for i in (0...indexPX).to_a.reverse
next if subpart.content[i] == " "
@isnum = Float(subpart.content[i]) rescue nil
break if @isnum.nil? == true || subpart.content[i] == ":"
end
if i != indexPX - 1
@arrofchangeString.push subpart.content[(i+1)..(indexPX+1)]
@arrofnewString.push ((subpart.content[(i+1)...(indexPX)].to_i / 16.0).to_s + "em")
end
end
@arrofchangeString.each_with_index do |changeString,i|
subpart.content = subpart.content.sub(changeString,@arrofnewString[i])
end
end
# change from px to em end
partials << subpart.content
end
end
end
@part_partials["data-pp='#{part.part_id}'"] = partials
end
@file = nil
@layout_html = nil
if original_view == "home"
@file = File.join("#{@key}", "/home/index.html.erb")
else
@file = File.join("#{@key}", "/home/page.html.erb")
end
@layout_html = render_to_string(@file , :formats => :html)
doc = Nokogiri::HTML(@layout_html, nil, "UTF-8")
head = doc.css("head")
@part_partials.each do |key, partial|
html_string = ""
partial.each do |p|
if !p.nil?
html_string = html_string + p
end
end
pp = doc.css("*[#{key}]")
if !pp.blank?
pp = pp[0]
pp.inner_html = html_string
end
end
if @editmode
pps = doc.css("*[data-pp]")
pps.each do |pp|
number = pp.attributes["data-pp"].value
if pp.inner_html.strip == ""
pp.inner_html = "<a href='/page_parts/new?part=#{number}&page_id=#{page.id.to_s}#{(!$mobile.blank? ? '&mobile_view=1' : '')}'> </a>"
else
inner_html = pp.inner_html
pp.inner_html = inner_html + "<a href='/page_parts/#{number}/edit?page_id=#{page.id.to_s}#{(!$mobile.blank? ? '&mobile_view=1' : '')}'> </a>"
end
end
end
if original_view != "home"
viewarea = doc.css("*[data-content='true']")[0]
viewarea.inner_html = render_to_string(original_view) rescue "<div></div>"
# change from px to em start
if viewarea.inner_html.include? "px"
@arrofindex = Array.new
@indexOfpx = viewarea.inner_html.index('px')
@arrofindex.push @indexOfpx
while @indexOfpx.nil? == false
@indexOfpx = viewarea.inner_html.index('px',@indexOfpx+1)
break if @indexOfpx.nil? == true
@arrofindex.push @indexOfpx
end
@arrofchangeString = Array.new
@arrofnewString = Array.new
@arrofindex.each do |indexPX|
for i in (0...indexPX).to_a.reverse
next if viewarea.inner_html[i] == " "
@isnum = Float(viewarea.inner_html[i]) rescue nil
break if @isnum.nil? == true || viewarea.inner_html[i] == ":"
end
if i != indexPX - 1
@arrofchangeString.push viewarea.inner_html[(i+1)..(indexPX+1)]
@arrofnewString.push ((viewarea.inner_html[(i+1)...(indexPX)].to_i / 16.0).to_s + "em")
end
end
@arrofchangeString.each_with_index do |changeString,i|
viewarea.inner_html = viewarea.inner_html.sub(changeString,@arrofnewString[i])
end
end
# change from px to em end
head[0].inner_html = OrbitHelper.meta_tags_html + head.inner_html
end
head[0].inner_html = head.inner_html + OrbitHelper.get_css_to_render_in_head
link = doc.css("link")[0]
link.attributes["href"].value = current_site.favicon.url.nil? ? "/assets/favicon.ico" : current_site.favicon.url
final_html_for_render = doc.to_html
else
final_html_for_render = render_to_string(original_view) rescue "<div></div>"
end
final_html_for_render = change_to_language(final_html_for_render)
if @editmode
session[:mobile] = $temp_mobile
end
format_date(final_html_for_render,(original_view == "home" ? "home" : page.module)) rescue final_html_for_render
end
def format_date(html,module_key)
doc = Nokogiri::HTML(html, nil, "UTF-8")
doc.css("body").first.set_attribute("data-module",module_key) rescue nil
dates = doc.css("*[date-format]")
if dates.blank?
return doc.to_html
else
dates.each do |d|
format = d.attributes["date-format"].value
date = DateTime.parse(d.inner_text)
d.inner_html = d.inner_html.gsub(d.inner_text.strip, " " + date.strftime(format))
end
return doc.to_html
end
end
def get_widget_path(widget)
file = File.join('../templates', "#{@key}", "modules/#{widget}")
end
def get_view
page = Page.find(params[:id]) rescue Page.root
if page == Page.root
@view = File.join(Rails.root, 'app', 'templates', "#{@key}", "home/index.html.erb")
else
module_name = page.module.downcase.singularize
@view = File.join(Rails.root, 'app', 'templates', "#{@key}", "modules/#{module_name}/index.html.erb")
end
end
def page_params
page = Page.find(params[:page][:parent_page])
page.url = page.url == "/" ? "" : page.url
@url = page.url + "/#{params[:page][:page_id]}"
valid_locales = current_site.valid_locales rescue []
p = params.require(:page).permit(:number, :page_type, :page_id, :module, :access_level, :layout, :parent_page, :data_count, :enabled_for_mobile, :member_sort_position, enabled_for_sitemap: [], enabled_for: [], menu_enabled_for: [], categories: [], tags: [], role_status: [], name_translations: valid_locales ,external_url_translations: valid_locales)
p["url"] = @url
if p["external_url_translations"]
current_site.in_use_locales.each do |loc|
p["external_url_translations"][loc.to_s] = p["external_url_translations"][loc.to_s].sub("http://" + request.host_with_port,"") if p["external_url_translations"][loc.to_s].present?
end
end
p
end
def page_update_params
valid_locales = current_site.valid_locales rescue []
p = params.require(:page).permit(:number, :page_type, :page_id, :module, :access_level, :layout, :parent_page, :data_count, :custom_string_field, :enabled_for_mobile, :member_sort_position, enabled_for_sitemap: [], enabled_for: [],menu_enabled_for: [], categories: [], tags: [], role_status: [], name_translations: valid_locales, external_url_translations: valid_locales)
p["role_status"] = p["role_status"] || []
p["categories"] = p["categories"] || []
p["tags"] = p["tags"] || []
p["enabled_for"] = p["enabled_for"] || []
p["menu_enabled_for"] = p["menu_enabled_for"] || []
p["enabled_for_sitemap"] = p["enabled_for_sitemap"] || []
p["enabled_for_mobile"] = p["enabled_for_mobile"] || 0
if p["external_url_translations"]
current_site.in_use_locales.each do |loc|
p["external_url_translations"][loc.to_s] = p["external_url_translations"][loc.to_s].sub("http://" + request.host_with_port,"") if p["external_url_translations"][loc.to_s].present?
end
end
p
end
def get_layout
if request[:action] == "edit_view"
page = Page.find(params[:id])
if page.page_id == "" || page.page_id == nil
false
else
File.join("../../templates", "#{@key}", "/home/page.html.erb")
end
# elsif request[:action] == "show" || request[:action] == "moduleShow"
# File.join("../../templates", "themes", "#{@key}", '/home/page.html.erb')
else
false
end
end
def to_bool(str)
return true if str == "true"
return false if str == "false"
end
def check_frontend_open
if !current_site.frontend_open && current_user.blank?
redirect_to '/admin/dashboards'
end
end
def check_authorization
if current_user.blank? or !current_user.is_admin?
redirect_to '/admin/dashboards'
end
end
def set_edit_mode
@dataApi = "frontend"
@editmode = false
if !current_user.nil? and current_user.is_admin?
if params[:editmode] == "on"
@editmode = true
@dataApi = "edit"
end
end
end
def change_to_language(final_html)
if session[:zh_cn]
final_html = ZhConv.convert("zh-cn", final_html,false)
final_html.gsub!('/zh_tw/','/zh_cn/')
final_html.sub!('<a accesskey="t" href="'+request.path+'">繁体中文</a>','<a accesskey="t" href="'+(request.path.sub('/zh_cn/','/zh_tw/'))+'">繁体中文</a>')
end
final_html
end
end