agile_rails 0.0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/MIT-LICENSE +20 -0
- data/README.md +285 -0
- data/Rakefile +39 -0
- data/agile_rails.gemspec +36 -0
- data/app/assets/fonts/ibm-plex-sans-300.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-400.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-500.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-600.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-700.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-italic.woff2 +0 -0
- data/app/assets/images/32px.png +0 -0
- data/app/assets/images/throbber.gif +0 -0
- data/app/assets/javascripts/agile/agile.js +1489 -0
- data/app/assets/javascripts/agile/jquery-migrate.js +702 -0
- data/app/assets/javascripts/agile/jquery.bpopup.js +372 -0
- data/app/assets/javascripts/agile/jquery.datetimepicker.js +1353 -0
- data/app/assets/javascripts/agile/jstree.min.js +6 -0
- data/app/assets/javascripts/agile/select-multiple.js +459 -0
- data/app/assets/javascripts/agile/some_scripts.js +33 -0
- data/app/assets/javascripts/agile.js +22 -0
- data/app/assets/javascripts/agile_application.js +22 -0
- data/app/assets/javascripts/agile_editor.js +22 -0
- data/app/assets/stylesheets/agile/agile.css +1882 -0
- data/app/assets/stylesheets/agile/agile_apps.css +149 -0
- data/app/assets/stylesheets/agile/jquery.datetimepicker.css +304 -0
- data/app/assets/stylesheets/agile/jstree.css +1107 -0
- data/app/assets/stylesheets/agile/select-multiple.css +110 -0
- data/app/assets/stylesheets/agile/th-bg.png +0 -0
- data/app/assets/stylesheets/agile/theme.css +49 -0
- data/app/assets/stylesheets/agile.css +21 -0
- data/app/assets/stylesheets/agile_application.css +20 -0
- data/app/assets/stylesheets/agile_editor.css +19 -0
- data/app/controllers/agile_application_controller.rb +735 -0
- data/app/controllers/agile_common_controller.rb +345 -0
- data/app/controllers/agile_controller.rb +977 -0
- data/app/controllers/agile_main_controller.rb +36 -0
- data/app/controls/agile_control.rb +120 -0
- data/app/controls/agile_report.rb +364 -0
- data/app/controls/ar_category_control.rb +39 -0
- data/app/controls/ar_help_control.rb +139 -0
- data/app/controls/ar_image_control.rb +180 -0
- data/app/controls/ar_journal_control.rb +47 -0
- data/app/controls/ar_menu_item_control.rb +55 -0
- data/app/controls/ar_page_control.rb +64 -0
- data/app/controls/ar_poll_result_control.rb +84 -0
- data/app/controls/ar_setup_control.rb +62 -0
- data/app/controls/belongs_to_control.rb +61 -0
- data/app/controls/browse_models_control.rb +98 -0
- data/app/controls/settings_form_control.rb +137 -0
- data/app/forms/agile_help.yml +112 -0
- data/app/forms/agile_menu.yml +140 -0
- data/app/forms/agile_report_defaults.yml +39 -0
- data/app/forms/all_options.yml +810 -0
- data/app/forms/ar_ad.yml +121 -0
- data/app/forms/ar_big_table.yml +60 -0
- data/app/forms/ar_big_table_value.yml +52 -0
- data/app/forms/ar_browse_fields.yml +35 -0
- data/app/forms/ar_browse_models.yml +48 -0
- data/app/forms/ar_category.yml +73 -0
- data/app/forms/ar_category_as_tree.yml +31 -0
- data/app/forms/ar_design.yml +75 -0
- data/app/forms/ar_filter.yml +52 -0
- data/app/forms/ar_folder_permission.yml +56 -0
- data/app/forms/ar_folder_rule.yml +48 -0
- data/app/forms/ar_gallery.yml +55 -0
- data/app/forms/ar_image.yml +126 -0
- data/app/forms/ar_image_search.yml +83 -0
- data/app/forms/ar_journal.yml +76 -0
- data/app/forms/ar_json_ld.yml +56 -0
- data/app/forms/ar_key_value.yml +33 -0
- data/app/forms/ar_key_value_store.yml +33 -0
- data/app/forms/ar_link.yml +60 -0
- data/app/forms/ar_menu.yml +67 -0
- data/app/forms/ar_menu_item.yml +141 -0
- data/app/forms/ar_page.yml +187 -0
- data/app/forms/ar_part.yml +91 -0
- data/app/forms/ar_permission.yml +52 -0
- data/app/forms/ar_permission_rule.yml +40 -0
- data/app/forms/ar_piece.yml +106 -0
- data/app/forms/ar_policy.yml +64 -0
- data/app/forms/ar_policy_rule.yml +42 -0
- data/app/forms/ar_policy_rule_nocms.yml +40 -0
- data/app/forms/ar_poll.yml +118 -0
- data/app/forms/ar_poll_item.yml +78 -0
- data/app/forms/ar_poll_result.yml +88 -0
- data/app/forms/ar_poll_result_export.yml +35 -0
- data/app/forms/ar_removed_url.yml +41 -0
- data/app/forms/ar_role.yml +43 -0
- data/app/forms/ar_seo.yml +32 -0
- data/app/forms/ar_setup.yml +45 -0
- data/app/forms/ar_site.yml +149 -0
- data/app/forms/ar_steps_template.yml +51 -0
- data/app/forms/ar_user.yml +140 -0
- data/app/forms/ar_user_role.yml +57 -0
- data/app/forms/help/dc_category_as_tree.en +4 -0
- data/app/forms/help/dc_category_as_tree.sl +5 -0
- data/app/forms/json_ld_schema.yml +168 -0
- data/app/helpers/agile_application_helper.rb +1162 -0
- data/app/helpers/agile_category_helper.rb +128 -0
- data/app/helpers/agile_common_helper.rb +308 -0
- data/app/helpers/agile_edit_helper.rb +645 -0
- data/app/helpers/agile_helper.rb +509 -0
- data/app/helpers/agile_index_helper.rb +677 -0
- data/app/helpers/ar_image_helper.rb +128 -0
- data/app/models/agile_form_fields/action.rb +61 -0
- data/app/models/agile_form_fields/agile_form_field.rb +322 -0
- data/app/models/agile_form_fields/belongs_to.rb +112 -0
- data/app/models/agile_form_fields/check_box.rb +73 -0
- data/app/models/agile_form_fields/comment.rb +62 -0
- data/app/models/agile_form_fields/date_picker.rb +104 -0
- data/app/models/agile_form_fields/date_select.rb +68 -0
- data/app/models/agile_form_fields/datetime_picker.rb +88 -0
- data/app/models/agile_form_fields/datetime_select.rb +73 -0
- data/app/models/agile_form_fields/file_field.rb +52 -0
- data/app/models/agile_form_fields/file_select.rb +69 -0
- data/app/models/agile_form_fields/hidden_field.rb +51 -0
- data/app/models/agile_form_fields/html_field.rb +69 -0
- data/app/models/agile_form_fields/journal_diff.rb +62 -0
- data/app/models/agile_form_fields/link_to.rb +69 -0
- data/app/models/agile_form_fields/method.rb +66 -0
- data/app/models/agile_form_fields/multitext_autocomplete.rb +215 -0
- data/app/models/agile_form_fields/number_field.rb +92 -0
- data/app/models/agile_form_fields/password_field.rb +63 -0
- data/app/models/agile_form_fields/radio_button.rb +95 -0
- data/app/models/agile_form_fields/readonly.rb +77 -0
- data/app/models/agile_form_fields/select.rb +281 -0
- data/app/models/agile_form_fields/submit_tag.rb +58 -0
- data/app/models/agile_form_fields/text_area.rb +61 -0
- data/app/models/agile_form_fields/text_autocomplete.rb +171 -0
- data/app/models/agile_form_fields/text_field.rb +55 -0
- data/app/models/agile_form_fields/text_with_select.rb +94 -0
- data/app/models/agile_form_fields/tree_select.rb +170 -0
- data/app/models/ar_big_table.rb +82 -0
- data/app/models/ar_big_table_value.rb +53 -0
- data/app/models/ar_category.rb +109 -0
- data/app/models/ar_design.rb +116 -0
- data/app/models/ar_filter.rb +200 -0
- data/app/models/ar_folder_permission.rb +50 -0
- data/app/models/ar_folder_rule.rb +47 -0
- data/app/models/ar_gallery.rb +53 -0
- data/app/models/ar_image.rb +198 -0
- data/app/models/ar_internals.rb +60 -0
- data/app/models/ar_journal.rb +46 -0
- data/app/models/ar_json_ld.rb +131 -0
- data/app/models/ar_key_value_store.rb +128 -0
- data/app/models/ar_link.rb +48 -0
- data/app/models/ar_memory.rb +172 -0
- data/app/models/ar_menu.rb +144 -0
- data/app/models/ar_menu_item.rb +106 -0
- data/app/models/ar_page.rb +74 -0
- data/app/models/ar_part.rb +66 -0
- data/app/models/ar_permission.rb +180 -0
- data/app/models/ar_permission_rule.rb +65 -0
- data/app/models/ar_policy.rb +78 -0
- data/app/models/ar_policy_rule.rb +65 -0
- data/app/models/ar_poll.rb +74 -0
- data/app/models/ar_poll_item.rb +47 -0
- data/app/models/ar_poll_result.rb +38 -0
- data/app/models/ar_removed_url.rb +42 -0
- data/app/models/ar_role.rb +84 -0
- data/app/models/ar_setup.rb +115 -0
- data/app/models/ar_site.rb +68 -0
- data/app/models/ar_temp.rb +150 -0
- data/app/models/ar_user.rb +72 -0
- data/app/models/ar_user_group.rb +38 -0
- data/app/models/ar_user_role.rb +54 -0
- data/app/models/ar_visit.rb +41 -0
- data/app/models/concerns/ar_page_concern.rb +128 -0
- data/app/models/concerns/ar_part_concern.rb +48 -0
- data/app/models/concerns/ar_piece_concern.rb +48 -0
- data/app/models/concerns/ar_policy_rule_concern.rb +87 -0
- data/app/models/concerns/ar_seo_concern.rb +66 -0
- data/app/models/concerns/ar_site_concern.rb +103 -0
- data/app/models/concerns/ar_user_concern.rb +195 -0
- data/app/renderers/agile_common_renderer.rb +93 -0
- data/app/renderers/agile_renderer.rb +59 -0
- data/app/renderers/ar_ad_renderer.rb +219 -0
- data/app/renderers/ar_captcha_renderer.rb +113 -0
- data/app/renderers/ar_common_renderer.rb +90 -0
- data/app/renderers/ar_gallery_renderer.rb +107 -0
- data/app/renderers/ar_menu_renderer.rb +195 -0
- data/app/renderers/ar_page_renderer.rb +147 -0
- data/app/renderers/ar_part_renderer.rb +235 -0
- data/app/renderers/ar_piece_renderer.rb +119 -0
- data/app/renderers/ar_poll_renderer.rb +272 -0
- data/app/views/agile/_edit_stuff.html.erb +57 -0
- data/app/views/agile/_form.html.erb +24 -0
- data/app/views/agile/_result.html.erb +28 -0
- data/app/views/agile/edit.html.erb +13 -0
- data/app/views/agile/error.html.erb +2 -0
- data/app/views/agile/index.html.erb +14 -0
- data/app/views/agile/login.html.erb +19 -0
- data/app/views/agile/new.html.erb +12 -0
- data/app/views/agile_common/_help.html.erb +18 -0
- data/app/views/agile_common/_iframe_edit.html.erb +2 -0
- data/app/views/agile_common/paste_clipboard.html.erb +17 -0
- data/app/views/layouts/agile.html.erb +17 -0
- data/app/views/layouts/content.html.erb +20 -0
- data/app/views/models/dump_models.html.erb +47 -0
- data/config/initializers/kaminari_patch.rb +56 -0
- data/config/locales/agile_de.yml +138 -0
- data/config/locales/agile_en.yml +162 -0
- data/config/locales/agile_sl.yml +163 -0
- data/config/locales/datetimepicker.yml +19 -0
- data/config/locales/de.yml +231 -0
- data/config/locales/en.yml +13 -0
- data/config/locales/kaminari.yml +26 -0
- data/config/locales/models_en.yml +1032 -0
- data/config/locales/models_sl.yml +1065 -0
- data/config/locales/sl.yml +211 -0
- data/db/migrate/20240120160001_add_sessions_table.rb +12 -0
- data/db/migrate/20240120160002_ar_big_table.rb +17 -0
- data/db/migrate/20240120160003_ar_big_table_value.rb +18 -0
- data/db/migrate/20240120160004_ar_category.rb +22 -0
- data/db/migrate/20240120160005_ar_design.rb +20 -0
- data/db/migrate/20240120160006_ar_filter.rb +17 -0
- data/db/migrate/20240120160007_ar_gallery.rb +21 -0
- data/db/migrate/20240120160008_ar_journal.rb +19 -0
- data/db/migrate/20240120160009_ar_key_value_store.rb +11 -0
- data/db/migrate/20240120160010_ar_link.rb +19 -0
- data/db/migrate/20240120160011_ar_memory.rb +8 -0
- data/db/migrate/20240120160012_ar_menu.rb +21 -0
- data/db/migrate/20240120160013_ar_menu_item.rb +28 -0
- data/db/migrate/20240120160014_ar_page.rb +50 -0
- data/db/migrate/20240120160015_ar_part.rb +33 -0
- data/db/migrate/20240120160016_ar_permission.rb +16 -0
- data/db/migrate/20240120160017_ar_permission_rule.rb +17 -0
- data/db/migrate/20240120160018_ar_piece.rb +28 -0
- data/db/migrate/20240120160019_ar_policy.rb +21 -0
- data/db/migrate/20240120160020_ar_policy_rule.rb +18 -0
- data/db/migrate/20240120160021_ar_poll.rb +27 -0
- data/db/migrate/20240120160022_ar_poll_item.rb +23 -0
- data/db/migrate/20240120160023_ar_poll_result.rb +14 -0
- data/db/migrate/20240120160024_ar_removed_url.rb +16 -0
- data/db/migrate/20240120160025_ar_role.rb +17 -0
- data/db/migrate/20240120160026_ar_site.rb +37 -0
- data/db/migrate/20240120160027_ar_temp.rb +11 -0
- data/db/migrate/20240120160028_ar_user.rb +42 -0
- data/db/migrate/20240120160029_ar_user_group.rb +12 -0
- data/db/migrate/20240120160030_ar_user_role.rb +18 -0
- data/db/migrate/20240120160031_ar_visit.rb +15 -0
- data/db/migrate/20240703016001_ar_setup.rb +16 -0
- data/db/migrate/20240703016002_ar_folder_permission.rb +15 -0
- data/db/migrate/20240703016003_ar_folder_rule.rb +14 -0
- data/db/migrate/20250115000001_ar_image.rb +25 -0
- data/lib/agile/configuration.rb +43 -0
- data/lib/agile/engine.rb +29 -0
- data/lib/agile/version.rb +27 -0
- data/lib/agile.rb +282 -0
- data/lib/agile_rails.rb +1 -0
- data/lib/generators/agile/USAGE +11 -0
- data/lib/generators/agile/new_form_generator.rb +369 -0
- data/lib/generators/convert_to_ar/convert_to_ar_generator.rb +158 -0
- data/lib/tasks/agile_db_clone.rake +132 -0
- data/lib/tasks/agile_db_export_to_yaml.rake +37 -0
- data/lib/tasks/agile_db_migrate.rake +35 -0
- metadata +414 -0
@@ -0,0 +1,735 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2024+ Damjan Rems
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#+
|
23
|
+
|
24
|
+
##########################################################################
|
25
|
+
# AgileApplicationController holds methods which are useful for all
|
26
|
+
# application controllers.
|
27
|
+
##########################################################################
|
28
|
+
class AgileApplicationController < ActionController::Base
|
29
|
+
protect_from_forgery with: :null_session, only: Proc.new { _1.request.format.json? }
|
30
|
+
before_action :agile_set_locale
|
31
|
+
|
32
|
+
########################################################################
|
33
|
+
# Writes anything passed as parameter to logger file.
|
34
|
+
# Very useful for debuging strange errors.
|
35
|
+
#
|
36
|
+
# @param [Objects] args any parameter can be passed
|
37
|
+
########################################################################
|
38
|
+
def agile_dump(*args)
|
39
|
+
args.each do |arg|
|
40
|
+
logger.info arg.to_s
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
####################################################################
|
45
|
+
# Return true if CMS is in edit mode
|
46
|
+
#
|
47
|
+
# @return [Boolean] True if user CMS edit mode is selected
|
48
|
+
####################################################################
|
49
|
+
def agile_edit_mode?
|
50
|
+
session[:edit_mode].to_i > 1
|
51
|
+
end
|
52
|
+
|
53
|
+
####################################################################
|
54
|
+
# Checks if user has required role.
|
55
|
+
#
|
56
|
+
# @param [ArRole or String] role can be passed as ArRole object or
|
57
|
+
# as role name. If passed as name, ar_policy_roles is searched for appropriate role.
|
58
|
+
#
|
59
|
+
# @return [Boolean] True if user has required role added to his profile.
|
60
|
+
#
|
61
|
+
# @example If user has required role
|
62
|
+
# if agile_user_has_role?('admin') ...
|
63
|
+
# if agile_user_has_role?('Site editors') ...
|
64
|
+
####################################################################
|
65
|
+
def agile_user_has_role?(role)
|
66
|
+
role = ArRole.get_role(role)
|
67
|
+
return false if role.nil? || session[:user_roles].nil?
|
68
|
+
# role exists in user_roles
|
69
|
+
session[:user_roles].include?(role.id)
|
70
|
+
end
|
71
|
+
|
72
|
+
####################################################################
|
73
|
+
# Determines site from url and returns site record.
|
74
|
+
#
|
75
|
+
# @return [ArSite] site record. If site is not found and not in production environment,
|
76
|
+
# 'development' record is returned. If site record has alias set then alias site record is
|
77
|
+
# returned.
|
78
|
+
#
|
79
|
+
# @example Returns Google analytics code from site settings
|
80
|
+
# settings = agile_get_site.params['ga_acc']
|
81
|
+
####################################################################
|
82
|
+
def agile_get_site
|
83
|
+
return @site if @site
|
84
|
+
|
85
|
+
uri = URI.parse(request.url)
|
86
|
+
cache_key = ['ar_site', uri.host]
|
87
|
+
@site = Agile.cache_read(cache_key)
|
88
|
+
return @site if @site
|
89
|
+
|
90
|
+
@site = ArSite.find_by(name: uri.host)
|
91
|
+
# Site can be aliased
|
92
|
+
if @site&.alias_for.present?
|
93
|
+
@site = ArSite.find_by(name: @site.alias_for)
|
94
|
+
end
|
95
|
+
# Development environment. Check if site with name development exists and use
|
96
|
+
# alias_for as pointer to our site.
|
97
|
+
if @site.nil? && !Rails.env.production?
|
98
|
+
@site = ArSite.find_by(name: 'development')
|
99
|
+
@site = ArSite.find_by(name: @site.alias_for) if @site
|
100
|
+
end
|
101
|
+
@site = nil unless @site&.active # might be disabled
|
102
|
+
Agile.cache_write(cache_key, @site)
|
103
|
+
end
|
104
|
+
|
105
|
+
##########################################################################
|
106
|
+
# Will set page title according to data on ar_page or ar_site
|
107
|
+
#
|
108
|
+
# Sets internal @page_title variable.
|
109
|
+
##########################################################################
|
110
|
+
def set_page_title
|
111
|
+
@page_title = @page.title.blank? ? @page.subject : @page.title
|
112
|
+
agile_add_meta_tag(:name, 'description', @page.meta_description)
|
113
|
+
end
|
114
|
+
|
115
|
+
#######################################################################
|
116
|
+
# Will render public/404.html file with some debug code includded.
|
117
|
+
#
|
118
|
+
# @param [Object] Object where_the_error_is. Additional data can be displayed with error.
|
119
|
+
#
|
120
|
+
# @example Render error
|
121
|
+
# site = agile_get_site()
|
122
|
+
# return agile_render_404('Site') unless site
|
123
|
+
########################################################################
|
124
|
+
def agile_render_404(where_the_error_is=nil)
|
125
|
+
logger.info("Error 404;#{request.env['REQUEST_URI'] rescue ''};#{request.referer};#{where_the_error_is}")
|
126
|
+
render(file: Rails.root.join('public/404.html'), status: 404)
|
127
|
+
end
|
128
|
+
|
129
|
+
########################################################################
|
130
|
+
# Will write record to ar_visits collection unless visit comes from robot.
|
131
|
+
# It also sets session[is_robot] variable to true if robot.
|
132
|
+
########################################################################
|
133
|
+
def agile_visit_log
|
134
|
+
if request.env["HTTP_USER_AGENT"] and request.env["HTTP_USER_AGENT"].match(/\(.*https?:\/\/.*\)/)
|
135
|
+
logger.info "ROBOT: #{Time.now.strftime('%Y.%m.%d %H:%M:%S')} id=#{@page.id} ip=#{request.remote_ip}."
|
136
|
+
session[:is_robot] = true
|
137
|
+
else
|
138
|
+
ArVisit.create(site_id: @site.id,
|
139
|
+
user_id: session[:user_id],
|
140
|
+
page_id: @page.id,
|
141
|
+
ip: request.remote_ip,
|
142
|
+
session_id: request.session_options[:id],
|
143
|
+
time: Time.now )
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
##########################################################################
|
148
|
+
# This is default page process action. It will search for site, page and
|
149
|
+
# design records, collect parameters from different objects, add CMS edit code if allowed
|
150
|
+
# and at the end render design.body or design.rails_view or site.rails_view.
|
151
|
+
#
|
152
|
+
# @example as defined in routes.rb
|
153
|
+
# get '*path' => 'agileapplication_controller#agileprocess_default_request'
|
154
|
+
# # or
|
155
|
+
# get '*path' => 'my_controller#page'
|
156
|
+
# # then in my_controller.rb
|
157
|
+
# def page
|
158
|
+
# agileprocess_default_request
|
159
|
+
# end
|
160
|
+
##########################################################################
|
161
|
+
def agile_process_default_request
|
162
|
+
session[:edit_mode] ||= 0
|
163
|
+
# Initialize parts
|
164
|
+
@parts = nil
|
165
|
+
@js, @css = '', ''
|
166
|
+
# find domain name in sites
|
167
|
+
@site = agile_get_site
|
168
|
+
# site not defined. render 404 error
|
169
|
+
return agile_render_404('Site!') if @site.nil?
|
170
|
+
|
171
|
+
agile_options_set(@site.settings)
|
172
|
+
# HOMEPAGE. When no parameters is set
|
173
|
+
params[:path] = @site.homepage_link if params[:id].nil? && params[:path].nil?
|
174
|
+
@options[:path] = params[:path].to_s.downcase.split('/')
|
175
|
+
params[:path] = @options[:path].first if @options[:path].size > 1
|
176
|
+
# some other process request. It should fail if not defined
|
177
|
+
return send(@site.request_processor) unless @site.request_processor.blank?
|
178
|
+
|
179
|
+
# Search for page
|
180
|
+
page_class = @site.page_klass
|
181
|
+
if params[:id]
|
182
|
+
@page = page_class.find_by(ar_site_id: [@site.id, nil], link: params[:id], active: true)
|
183
|
+
@page = page_class.find(params[:id]) if @page.nil? # there will be more link searchers than by id
|
184
|
+
elsif params[:path]
|
185
|
+
# path may point direct to page's link
|
186
|
+
@page = page_class.find_by( :ar_site_id => [@site.id, nil], link: params[:path], active: true)
|
187
|
+
if @page.nil?
|
188
|
+
# no. Find if defined in links
|
189
|
+
if (link = ArLink.find_by( :ar_site_id => [@site.id, nil], link: params[:path]))
|
190
|
+
if link.page_id
|
191
|
+
agile_options_set link.params
|
192
|
+
@page = page_class.find(link.page_id)
|
193
|
+
else
|
194
|
+
redirect_to(link.redirect, allow_other_host: true) and return
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
# if @page is not found render 404 error
|
200
|
+
return agile_render_404('Page!') unless @page
|
201
|
+
|
202
|
+
agile_mobile_set unless session[:is_mobile] # do it only once per session
|
203
|
+
# find design if defined. Otherwise design MUST be declared in site
|
204
|
+
if @page.ar_design_id
|
205
|
+
@design = ArDesign.find(@page.ar_design_id)
|
206
|
+
return agile_render_404('Design!') unless @design
|
207
|
+
end
|
208
|
+
agile_options_set(@design.params) if @design
|
209
|
+
agile_options_set(@page.params)
|
210
|
+
#agile_add_json_ld(@page.get_json_ld)
|
211
|
+
# Add edit menu
|
212
|
+
if session[:edit_mode] > 0
|
213
|
+
session[:site_id] = @site.id
|
214
|
+
session[:site_page_class] = @site.page_class
|
215
|
+
session[:page_id] = @page.id
|
216
|
+
else
|
217
|
+
# Log visits from non-editors
|
218
|
+
#agile_visit_log()
|
219
|
+
end
|
220
|
+
set_page_title()
|
221
|
+
agile_render_design(@design)
|
222
|
+
end
|
223
|
+
|
224
|
+
protected
|
225
|
+
|
226
|
+
###########################################################################
|
227
|
+
# Checks if user can perform (read, create, edit, delete) record in specified table.
|
228
|
+
#
|
229
|
+
# @param [Integer] permission: Required permission level
|
230
|
+
# @param [String] table: Collection (table) name for which permission is queried. Defaults to params[table].
|
231
|
+
#
|
232
|
+
# @return [Boolean] true if user's role permits (is higher or equal then required) operation on a table (table).
|
233
|
+
#
|
234
|
+
# @Example True when user has view permission on the table
|
235
|
+
# if agile_user_can(ArPermission::CAN_VIEW, params[:table]) then ...
|
236
|
+
############################################################################
|
237
|
+
def agile_user_can(permission, table = AgileHelper.table_param(params))
|
238
|
+
table = table.underscore
|
239
|
+
cache_key = ['ar_permission', table, session[:user_id], agile_get_site.id]
|
240
|
+
permissions = Agile.cache_read(cache_key) { ArPermission.permissions_for_table(table) }
|
241
|
+
session[:user_roles].find { permissions[_1] && permissions[_1] >= permission }
|
242
|
+
end
|
243
|
+
|
244
|
+
####################################################################
|
245
|
+
# Detects if called from mobile agent according to http://detectmobilebrowsers.com/
|
246
|
+
# and set session[:is_mobile]
|
247
|
+
#
|
248
|
+
# Detect also if caller is a robot and set session[:is_robot]
|
249
|
+
####################################################################
|
250
|
+
def agile_mobile_set
|
251
|
+
is_mobile = request.user_agent ? /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.match(request.user_agent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.match(request.user_agent[0..3])
|
252
|
+
: false
|
253
|
+
session[:is_mobile] = is_mobile ? 1 : 0
|
254
|
+
|
255
|
+
if request.env["HTTP_USER_AGENT "] && request.env["HTTP_USER_AGENT"].match(/\(.*https?:\/\/.*\)/)
|
256
|
+
logger.info "ROBOT: #{Time.now.strftime('%Y.%m.%d %H:%M:%S')} id=#{@page.id} ip=#{request.remote_ip}."
|
257
|
+
session[:is_robot] = true
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
##########################################################################
|
262
|
+
# Merge values from parameters fields (from site, page ...) into internal @options hash.
|
263
|
+
#
|
264
|
+
# @param [String] parameters: passed as YAML string.
|
265
|
+
##########################################################################
|
266
|
+
def agile_options_set(parameters)
|
267
|
+
@options ||= {}
|
268
|
+
return if parameters.to_s.size < 3
|
269
|
+
# parameters are set as YAML. This should be default in future.
|
270
|
+
parms = YAML.load(parameters) rescue {}
|
271
|
+
@options = @options.deep_merge(parms) if parms.present?
|
272
|
+
end
|
273
|
+
|
274
|
+
##########################################################################
|
275
|
+
# Check if record(s) has been modified since last visit. It turned out that caching
|
276
|
+
# is not that simple and that there are multiple caching scenarios that can be used.
|
277
|
+
# So this code is here just for a example, how records can be checked for changed status.
|
278
|
+
#
|
279
|
+
# @param [records] List of records which are checked against last visit date
|
280
|
+
#
|
281
|
+
# @return [Boolean] true when none of documents is changed.
|
282
|
+
##########################################################################
|
283
|
+
def agile_not_modified?(*records)
|
284
|
+
return false unless request.env.include? 'HTTP_IF_MODIFIED_SINCE'
|
285
|
+
|
286
|
+
since_date = Time.parse request.env['HTTP_IF_MODIFIED_SINCE']
|
287
|
+
last_modified = since_date
|
288
|
+
records.each do |record|
|
289
|
+
next unless record.respond_to?(:updated_at)
|
290
|
+
last_modified = record.updated_at if record.updated_at > last_modified
|
291
|
+
end
|
292
|
+
|
293
|
+
if last_modified >= since_date then
|
294
|
+
render :nothing => true, :status => 304
|
295
|
+
return true
|
296
|
+
end
|
297
|
+
false
|
298
|
+
end
|
299
|
+
|
300
|
+
##########################################################################
|
301
|
+
# Will determine design content or view filename which defines design.
|
302
|
+
#
|
303
|
+
# Returns:
|
304
|
+
# design_body: design body as defined in site or design record.
|
305
|
+
# design_view: view file name which will be used for rendering design
|
306
|
+
##########################################################################
|
307
|
+
def agile_render_design(design_record)
|
308
|
+
layout = @site.site_layout.blank? ? 'content' : @site.site_layout
|
309
|
+
site_top = '<%= agile_page_top %>'
|
310
|
+
site_bottom = '<%= agile_page_bottom %>'
|
311
|
+
# the rails way
|
312
|
+
if @options[:control] && @options[:action]
|
313
|
+
controller = "#{@options[:control]}_control".classify.constantize rescue nil
|
314
|
+
extend controller if controller
|
315
|
+
return send @options[:action] if respond_to?(@options[:action])
|
316
|
+
end
|
317
|
+
# design record present
|
318
|
+
if design_record
|
319
|
+
# defined as rails view
|
320
|
+
design = if design_record.rails_view.blank? || design_record.rails_view == 'site'
|
321
|
+
@site.rails_view
|
322
|
+
else
|
323
|
+
design_record.rails_view
|
324
|
+
end
|
325
|
+
return render design, layout: layout unless design.blank?
|
326
|
+
# defined as inline code
|
327
|
+
design = design_record.body.blank? ? @site.design : design_record.body
|
328
|
+
design = site_top + design + site_bottom
|
329
|
+
return render(inline: design, layout: layout) unless design.blank?
|
330
|
+
end
|
331
|
+
# Design record not defined
|
332
|
+
if @site.rails_view.blank?
|
333
|
+
design = site_top + @site.design + site_bottom
|
334
|
+
render(inline: design, layout: layout)
|
335
|
+
else
|
336
|
+
render @site.rails_view, layout: layout
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
########################################################################
|
341
|
+
# Decamelize string. Does opposite of camelize method. It probably doesn't work
|
342
|
+
# very good with non ascii chars. Since this method is used for converting from model
|
343
|
+
# to collection names it is very unwise to use non ascii chars for table (table) names.
|
344
|
+
#
|
345
|
+
# @param [Object] model_string to be converted
|
346
|
+
#
|
347
|
+
# @example
|
348
|
+
# decamelize_type(ModelName) # 'ModelName' => 'model_name'
|
349
|
+
########################################################################
|
350
|
+
def decamelize_type(model_string)
|
351
|
+
model_string ? model_string.to_s.underscore : nil
|
352
|
+
end
|
353
|
+
|
354
|
+
####################################################################
|
355
|
+
# Return's error messages for the document formated for display on edit form.
|
356
|
+
#
|
357
|
+
# @param [Document] document object which will be examined for errors.
|
358
|
+
#
|
359
|
+
# @return [String] HTML code for displaying error on edit form.
|
360
|
+
####################################################################
|
361
|
+
def agile_error_messages_for(document)
|
362
|
+
return '' unless document.errors.any?
|
363
|
+
|
364
|
+
msg = document.errors.inject('') do |r, error|
|
365
|
+
label = t("helpers.label.#{decamelize_type(document.class)}.#{error.attribute}")
|
366
|
+
label = error.attribute if label.match( /translation missing/i )
|
367
|
+
r += "<li>#{label} : #{error.message}</li>"
|
368
|
+
end
|
369
|
+
|
370
|
+
%(
|
371
|
+
<div class="ar-form-error">
|
372
|
+
<h2>#{t('agile.errors_no')} #{document.errors.size}</h2>
|
373
|
+
<ul>#{msg}</ul>
|
374
|
+
</div>).html_safe
|
375
|
+
end
|
376
|
+
|
377
|
+
######################################################################
|
378
|
+
# Call rake task from controller.
|
379
|
+
#
|
380
|
+
# @param [String] task: Arke task name
|
381
|
+
# @param [Hash] options: Options that will be send to task as environment variables
|
382
|
+
#
|
383
|
+
# @example Call rake task from application
|
384
|
+
# agile_call_rake('clear:all', some_parm: some_id)
|
385
|
+
######################################################################
|
386
|
+
def agile_call_rake(task, options = {})
|
387
|
+
options[:rails_env] ||= Rails.env
|
388
|
+
args = options.map { |o, v| "#{o.to_s.upcase}='#{v}'" }
|
389
|
+
system "rake #{task} #{args.join(' ')} --trace 2>&1 >> #{Rails.root}/log/rake.log &"
|
390
|
+
end
|
391
|
+
|
392
|
+
######################################################################
|
393
|
+
# A helper for rendering ajax return code from controller. When ajax call is
|
394
|
+
# made from Agile form return may be quite complicated. All ajax return combinations
|
395
|
+
# can be found in agile.js file.
|
396
|
+
#
|
397
|
+
# @param [Hash] opts: Options
|
398
|
+
#
|
399
|
+
# @return [JSON Response] Formatted to be used for ajax return.
|
400
|
+
#
|
401
|
+
# @example
|
402
|
+
# html_code = '<span>Some text</span>'
|
403
|
+
# agile_render_ajax(div: 'mydiv', prepand: html_code) # Will prepand code to mydiv div
|
404
|
+
# agile_render_ajax(class: 'myclass', append: html_code) # Will append code to all objects with myclass class
|
405
|
+
# agile_render_ajax(operation: 'window', value: "/pdf_file.pdf") # will open pdf file in new window.
|
406
|
+
#
|
407
|
+
######################################################################
|
408
|
+
def agile_render_ajax(opts)
|
409
|
+
result = {}
|
410
|
+
if opts[:div] || opts[:class]
|
411
|
+
selector = opts[:div] ? '#' : '.' # for div . for class
|
412
|
+
key = case
|
413
|
+
when opts[:prepend] then "#{selector}+div"
|
414
|
+
when opts[:append] then "#{selector}div+"
|
415
|
+
else "#{selector}div"
|
416
|
+
end
|
417
|
+
key += "_#{opts[:div]}#{opts[:class]}"
|
418
|
+
else
|
419
|
+
logger.error 'Error: agile_render_ajax. Operation is not set!' if opts[:operation].nil?
|
420
|
+
key = "#{opts[:operation]}_"
|
421
|
+
end
|
422
|
+
result[key] = opts[:value] || opts[:url] || ''
|
423
|
+
render json: result
|
424
|
+
end
|
425
|
+
|
426
|
+
########################################################################
|
427
|
+
# Find document by parameters. This is how AgileRails finds document based on url parameters.
|
428
|
+
#
|
429
|
+
# @param [String] Table name. Could be ar_page;ar_part;... when searching for embedded document.
|
430
|
+
# @param [String] Id of the document
|
431
|
+
# @param [String] Ids of parent documents when document is embedded. Ids are separated by ; char.
|
432
|
+
#
|
433
|
+
# @return [document]. Required document or nil if not found.
|
434
|
+
#
|
435
|
+
# @example As used in agile_controller
|
436
|
+
# agile_document_find(params[:table], params[:id])
|
437
|
+
########################################################################
|
438
|
+
def agile_document_find(table, id)
|
439
|
+
table.classify.constantize.find(id)
|
440
|
+
end
|
441
|
+
|
442
|
+
########################################################################
|
443
|
+
# Reload patches in development. Since patching files are not automatically loaded in
|
444
|
+
# development environment this little method automatically reloads all patch files
|
445
|
+
# found in Agile.paths(:patches) path array.
|
446
|
+
########################################################################
|
447
|
+
def agile_reload_patches
|
448
|
+
Agile.paths(:patches).each do |patches|
|
449
|
+
Dir["#{patches}/**/*.rb"].each { |file| require_dependency(file) }
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
453
|
+
########################################################################
|
454
|
+
# Will set new default locale for application
|
455
|
+
#
|
456
|
+
# @param [String] new_locale : New locale value. If omitted it will be provided from params[:locale].
|
457
|
+
# if new_locale value is blank, application's default_locale will be used.
|
458
|
+
########################################################################
|
459
|
+
def agile_set_locale(new_locale = params[:locale])
|
460
|
+
if new_locale && new_locale != session[:locale]
|
461
|
+
session[:locale] = new_locale.blank? ? nil : new_locale.to_sym
|
462
|
+
end
|
463
|
+
I18n.locale = session[:locale] || I18n.default_locale
|
464
|
+
end
|
465
|
+
|
466
|
+
############################################################################
|
467
|
+
# Writes out deprication msg. It also adds site_name to message, so it is easier to
|
468
|
+
# find where the message is comming from.
|
469
|
+
############################################################################
|
470
|
+
def agile_deprecate(msg)
|
471
|
+
ActiveSupport::Deprecation.warn("#{ agile_get_site.name}: #{msg}")
|
472
|
+
end
|
473
|
+
|
474
|
+
####################################################################
|
475
|
+
# Clears all session data related to login.
|
476
|
+
####################################################################
|
477
|
+
def clear_login_data
|
478
|
+
session[:edit_mode] = 0
|
479
|
+
session[:user_id] = nil
|
480
|
+
session[:user_name] = nil
|
481
|
+
session[:user_roles] = []
|
482
|
+
set_default_guest_user_role
|
483
|
+
cookies.delete :remember_me
|
484
|
+
end
|
485
|
+
|
486
|
+
############################################################################
|
487
|
+
# Sets at least default guest user to user roles when no user is set.
|
488
|
+
############################################################################
|
489
|
+
def set_default_guest_user_role
|
490
|
+
guest = ArRole.get_role('guest')
|
491
|
+
session[:user_roles] = [guest.id] if guest
|
492
|
+
end
|
493
|
+
|
494
|
+
####################################################################
|
495
|
+
# Fills session with data related to successful login.
|
496
|
+
#
|
497
|
+
# @param [ArUser] user : User's document
|
498
|
+
# @param [Boolean] remember_me : false by default
|
499
|
+
####################################################################
|
500
|
+
def set_login_data(user, remember_me = false)
|
501
|
+
clear_login_data
|
502
|
+
return unless user&.active
|
503
|
+
|
504
|
+
session[:user_id] = user.id
|
505
|
+
session[:user_name] = user.name.squish
|
506
|
+
# special for SUPERADMIN
|
507
|
+
sa = ArRole.get_role('superadmin')
|
508
|
+
if sa && user.has_role?(sa.id)
|
509
|
+
session[:user_roles] << sa.id
|
510
|
+
session[:edit_mode] = 2
|
511
|
+
return
|
512
|
+
end
|
513
|
+
|
514
|
+
# read default policy from site. Policy might be inherited from other site
|
515
|
+
site = agile_get_site()
|
516
|
+
site = ArSite.find(policy_site.inherit_policy) if site.inherit_policy
|
517
|
+
default_policy = site.default_policy
|
518
|
+
|
519
|
+
# select only roles defined in default site policy and set edit_mode
|
520
|
+
user.roles.each do |role_id|
|
521
|
+
# check if role is active in this site
|
522
|
+
policy_role = default_policy.find { |role| role.ar_role_id == role_id }
|
523
|
+
next unless policy_role&.active
|
524
|
+
# set edit_mode
|
525
|
+
session[:edit_mode] = 1 if policy_role.permission > 1
|
526
|
+
session[:user_roles] << role_id
|
527
|
+
end
|
528
|
+
|
529
|
+
# Save remember me cookie if user doesn't have editor rights
|
530
|
+
if session[:edit_mode] == 0 && remember_me
|
531
|
+
cookies.signed[:remember_me] = { value: user.id, expires: 180.days.from_now }
|
532
|
+
end
|
533
|
+
end
|
534
|
+
|
535
|
+
##########################################################################
|
536
|
+
# Will check if user's login data is still valid and reload user roles.
|
537
|
+
#
|
538
|
+
# @param [Time] repeat_after : Check is repeated after time. This is by default performed every 24 hours.
|
539
|
+
##########################################################################
|
540
|
+
def agile_user_rights_check(repeat_after = 1.day)
|
541
|
+
return if session[:user_id].nil?
|
542
|
+
# last check more than repeat_after ago
|
543
|
+
if (session[:user_chk] ||= Time.now) < repeat_after.ago
|
544
|
+
user_id = session[:user_id]
|
545
|
+
clear_login_data()
|
546
|
+
# reload user roles
|
547
|
+
user = ArUser.find( user_id ) rescue nil
|
548
|
+
set_login_data(user)
|
549
|
+
session[:user_chk] = Time.now
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
553
|
+
##########################################################################
|
554
|
+
# Evaluates Class.method in more predictable context then just calling eval
|
555
|
+
#
|
556
|
+
# @param [String] class_method defined as MyClass.method_name
|
557
|
+
# @param [Object] params: optional parameters send to class_method
|
558
|
+
##########################################################################
|
559
|
+
def agile_class_method_eval(class_method, params = nil)
|
560
|
+
klass, method = class_method.split('.')
|
561
|
+
# check if class exists
|
562
|
+
klass = klass.classify.constantize rescue nil
|
563
|
+
if klass.nil?
|
564
|
+
logger.error " Class in #{class_method} not defined!"
|
565
|
+
return nil
|
566
|
+
end
|
567
|
+
# call method
|
568
|
+
if klass.respond_to?(method)
|
569
|
+
klass.send(method, params)
|
570
|
+
else
|
571
|
+
logger.error "Method in #{class_method} not defined!"
|
572
|
+
nil
|
573
|
+
end
|
574
|
+
end
|
575
|
+
|
576
|
+
##########################################################################
|
577
|
+
# Will add new element to json_ld structure
|
578
|
+
#
|
579
|
+
# Parameters:
|
580
|
+
# [element] Hash or Array of hashes:
|
581
|
+
##########################################################################
|
582
|
+
def agile_add_json_ld(element)
|
583
|
+
@json_ld ||= []
|
584
|
+
if element.class == Array
|
585
|
+
@json_ld += element
|
586
|
+
else
|
587
|
+
@json_ld << element
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
########################################################################
|
592
|
+
# Will add a meta tag to internal hash structure. If meta tag already exists it
|
593
|
+
# will be overwritten.
|
594
|
+
#
|
595
|
+
# Parameters:
|
596
|
+
# [name] String: meta name
|
597
|
+
# [content] String: meta content
|
598
|
+
#
|
599
|
+
########################################################################
|
600
|
+
def agile_add_meta_tag(type, name, content)
|
601
|
+
return if content.blank?
|
602
|
+
|
603
|
+
@meta_tags ||= {}
|
604
|
+
key = "#{type}=\"#{name}\""
|
605
|
+
@meta_tags[key] = content
|
606
|
+
end
|
607
|
+
|
608
|
+
########################################################################
|
609
|
+
# Will prepare flash[:update] which is used for updating elements on parent form.
|
610
|
+
#
|
611
|
+
# Parameters passed as hash:
|
612
|
+
# [field] String: Field name
|
613
|
+
# [head] String: Field name to be updated in head of form
|
614
|
+
# [value] String: New value
|
615
|
+
# [readonly] Boolean: Field is readonly
|
616
|
+
#
|
617
|
+
########################################################################
|
618
|
+
def agile_update_form_element(field: nil, head: nil, value:, readonly: true)
|
619
|
+
key = if field
|
620
|
+
(readonly ? 'td_' : '') + "record_#{field}"
|
621
|
+
elsif head
|
622
|
+
"head-#{head}"
|
623
|
+
end
|
624
|
+
return if key.nil?
|
625
|
+
|
626
|
+
flash[:update] ||= {}
|
627
|
+
flash[:update][key] = value
|
628
|
+
end
|
629
|
+
|
630
|
+
private
|
631
|
+
|
632
|
+
########################################################################
|
633
|
+
# Extends AgileRails form file. Extended file is processed first and then merged
|
634
|
+
# with code in current form file.
|
635
|
+
#
|
636
|
+
# Form can extend more than one form file. If so, form names must then be delimited with comma.
|
637
|
+
#
|
638
|
+
# [Parameters:]
|
639
|
+
# [extend_option] : Value of @form['extend'] option
|
640
|
+
########################################################################
|
641
|
+
def agile_form_extend(extend_option)
|
642
|
+
extend_option.chomp.split(',').each do |a_file|
|
643
|
+
form_file_name = AgileHelper.form_file_find(a_file.strip)
|
644
|
+
@form_js += form_read_js(form_file_name)
|
645
|
+
form = YAML.load_file( form_file_name )
|
646
|
+
@form = AgileHelper.forms_merge(form, @form)
|
647
|
+
# If combined form contains tabs and fields options, move fields into fields tab
|
648
|
+
if @form.dig('form', 'tabs') && @form.dig('form', 'fields')
|
649
|
+
@form['form']['tabs']['fields'] = @form['form']['fields']
|
650
|
+
@form['form']['fields'] = nil
|
651
|
+
end
|
652
|
+
end
|
653
|
+
end
|
654
|
+
|
655
|
+
########################################################################
|
656
|
+
# Include code from another AgileRails form file. Included code is merged
|
657
|
+
# with current form file code. Form can include more than one AgileRails forms. If so, form names must
|
658
|
+
# be delimited with comma.
|
659
|
+
#
|
660
|
+
# [Parameters:]
|
661
|
+
# [include_option] : Value of @form['include'] option
|
662
|
+
########################################################################
|
663
|
+
def agile_form_include(include_option)
|
664
|
+
includes = include_option.class == Array ? include_option : include_option.split(/\,|\;/)
|
665
|
+
includes.each do |include_file|
|
666
|
+
form_file_name = AgileHelper.form_file_find(include_file)
|
667
|
+
@form_js += form_read_js(form_file_name)
|
668
|
+
form = YAML.load_file(form_file_name)
|
669
|
+
@form = AgileHelper.forms_merge(@form, form)
|
670
|
+
end
|
671
|
+
end
|
672
|
+
|
673
|
+
########################################################################
|
674
|
+
# Will read data from form_file_name.js if exists.
|
675
|
+
#
|
676
|
+
# [Parameters:]
|
677
|
+
# [form_file_name] : Physical form filename
|
678
|
+
########################################################################
|
679
|
+
def form_read_js(form_file_name)
|
680
|
+
js_form_file_name = form_file_name.sub('.yml', '.js')
|
681
|
+
File.exist?(js_form_file_name) ? File.read(js_form_file_name) : ''
|
682
|
+
end
|
683
|
+
|
684
|
+
########################################################################
|
685
|
+
# Read AgileRails form into @form object. Subroutine of authorization_check
|
686
|
+
########################################################################
|
687
|
+
def agile_form_read
|
688
|
+
params[:table] ||= params[:t] || AgileHelper.form_param(params)
|
689
|
+
table_name = decamelize_type(AgileHelper.table_param(params).strip)
|
690
|
+
@tables = table_name.split(';').map{ [(_1.classify.constantize rescue nil), _1] }
|
691
|
+
|
692
|
+
# split ids passed when embedded document
|
693
|
+
@ids = params[:ids].to_s.strip.downcase.split(';')
|
694
|
+
|
695
|
+
# form_name defaults to last table specified
|
696
|
+
form_name = AgileHelper.form_param(params) || @tables.last[1]
|
697
|
+
@form_js = ''
|
698
|
+
|
699
|
+
# dynamically generated form
|
700
|
+
@form = if AgileHelper.form_param(params) == 'method'
|
701
|
+
agile_class_method_eval(params[:form_method], params)
|
702
|
+
else
|
703
|
+
form_file_name = AgileHelper.form_file_find(form_name)
|
704
|
+
@form_js = form_read_js(form_file_name)
|
705
|
+
YAML.load_file(form_file_name)
|
706
|
+
end
|
707
|
+
|
708
|
+
# form includes or extends another form file
|
709
|
+
agile_form_include(@form['include']) if @form['include']
|
710
|
+
agile_form_extend(@form['extend']) if @form['extend']
|
711
|
+
@form['script'] = @form['script'].to_s + @form_js
|
712
|
+
# add readonly key to form if readonly parameter is passed in url
|
713
|
+
@form['readonly'] = 1 if params['readonly']
|
714
|
+
|
715
|
+
# !!!!!! Always use strings for key names since @form_params['table'] != @form_params[:table]
|
716
|
+
@form_params = { 'table' => table_name, 'ids' => params[:ids], 'form_name' => form_name,
|
717
|
+
'return_to' => params['return_to'], 'edit_only' => params['edit_only'],
|
718
|
+
'readonly' => params['readonly'], 'window_close' => params['window_close'],
|
719
|
+
'belongs_to' => params[:belongs_to], 'belongs_to_id' => params[:belongs_to_id]
|
720
|
+
}
|
721
|
+
end
|
722
|
+
|
723
|
+
########################################################################
|
724
|
+
# Will search for help file and return it's full path name if found.
|
725
|
+
########################################################################
|
726
|
+
def self.find_help_file(help_file_name)
|
727
|
+
file_name = nil
|
728
|
+
Agile.paths(:forms).reverse.each do |path|
|
729
|
+
f = "#{path}/help/#{help_file_name}.#{I18n.locale}"
|
730
|
+
file_name = f and break if File.exist?(f)
|
731
|
+
end
|
732
|
+
file_name
|
733
|
+
end
|
734
|
+
|
735
|
+
end
|