drg_cms 0.6.0.8 → 0.6.1.5

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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -10
  3. data/app/assets/javascripts/drg_cms/drg_cms.js +208 -81
  4. data/app/assets/stylesheets/drg_cms/drg_cms.css +298 -93
  5. data/app/assets/stylesheets/drg_cms/select-multiple.css +1 -1
  6. data/app/controllers/cmsedit_controller.rb +174 -167
  7. data/app/controllers/dc_application_controller.rb +230 -196
  8. data/app/controllers/dc_common_controller.rb +88 -50
  9. data/app/controls/dc_help_control.rb +138 -0
  10. data/app/controls/dc_report.rb +12 -16
  11. data/app/forms/all_options.yml +14 -5
  12. data/app/forms/cms_menu.yml +7 -1
  13. data/app/forms/dc_big_table.yml +0 -2
  14. data/app/forms/dc_big_table_value.yml +0 -2
  15. data/app/forms/dc_category.yml +2 -1
  16. data/app/forms/dc_design.yml +2 -2
  17. data/app/forms/dc_folder_permission.yml +0 -2
  18. data/app/forms/dc_help_1.yml +110 -0
  19. data/app/forms/dc_journal.yml +3 -1
  20. data/app/forms/dc_json_ld.yml +0 -3
  21. data/app/forms/dc_link.yml +1 -1
  22. data/app/forms/dc_menu.yml +8 -12
  23. data/app/forms/dc_menu_item.yml +2 -3
  24. data/app/forms/dc_page.yml +7 -2
  25. data/app/forms/dc_part.yml +1 -0
  26. data/app/forms/dc_piece.yml +1 -0
  27. data/app/forms/dc_policy.yml +2 -5
  28. data/app/forms/dc_poll.yml +13 -16
  29. data/app/forms/dc_seo.yml +1 -2
  30. data/app/forms/dc_simple_menu.yml +3 -2
  31. data/app/forms/dc_site.yml +5 -8
  32. data/app/forms/dc_user.yml +27 -11
  33. data/app/forms/dc_user_role.yml +3 -0
  34. data/app/helpers/cms_common_helper.rb +68 -4
  35. data/app/helpers/cms_edit_helper.rb +73 -55
  36. data/app/helpers/cms_helper.rb +70 -32
  37. data/app/helpers/cms_index_helper.rb +155 -102
  38. data/app/helpers/dc_application_helper.rb +132 -109
  39. data/app/models/concerns/dc_page_concern.rb +14 -4
  40. data/app/models/concerns/dc_piece_concern.rb +1 -1
  41. data/app/models/concerns/dc_policy_rule_concern.rb +20 -8
  42. data/app/models/concerns/dc_site_concern.rb +56 -44
  43. data/app/models/concerns/dc_user_concern.rb +58 -19
  44. data/app/models/dc_big_table.rb +2 -2
  45. data/app/models/dc_design.rb +29 -19
  46. data/app/models/dc_filter.rb +28 -22
  47. data/app/models/dc_key_value_store.rb +1 -0
  48. data/app/models/dc_permission.rb +19 -9
  49. data/app/models/dc_policy.rb +25 -14
  50. data/app/models/dc_policy_role.rb +22 -11
  51. data/app/models/dc_temp.rb +8 -1
  52. data/app/models/dc_user_role.rb +2 -2
  53. data/app/models/drgcms_form_fields/comment.rb +11 -2
  54. data/app/models/drgcms_form_fields/date_picker.rb +2 -0
  55. data/app/models/drgcms_form_fields/drgcms_field.rb +2 -1
  56. data/app/models/drgcms_form_fields/embedded.rb +9 -10
  57. data/app/models/drgcms_form_fields/file_field.rb +1 -1
  58. data/app/models/drgcms_form_fields/file_select.rb +2 -2
  59. data/app/models/drgcms_form_fields/hash_field.rb +11 -7
  60. data/app/models/drgcms_form_fields/link_to.rb +2 -2
  61. data/app/models/drgcms_form_fields/method.rb +5 -4
  62. data/app/models/drgcms_form_fields/multitext_autocomplete.rb +1 -1
  63. data/app/models/drgcms_form_fields/number_field.rb +4 -3
  64. data/app/models/drgcms_form_fields/readonly.rb +13 -17
  65. data/app/models/drgcms_form_fields/select.rb +24 -25
  66. data/app/models/drgcms_form_fields/text_autocomplete.rb +22 -14
  67. data/app/renderers/dc_page_renderer.rb +7 -6
  68. data/app/renderers/dc_poll_renderer.rb +16 -20
  69. data/app/views/cmsedit/_edit_stuff.html.erb +5 -2
  70. data/app/views/cmsedit/_form.html.erb +3 -2
  71. data/app/views/cmsedit/_result.html.erb +21 -18
  72. data/app/views/cmsedit/edit.html.erb +4 -1
  73. data/app/views/cmsedit/index.html.erb +3 -2
  74. data/app/views/cmsedit/new.html.erb +5 -2
  75. data/app/views/dc_common/_help.html.erb +17 -0
  76. data/app/views/layouts/models.html.erb +2 -1
  77. data/config/locales/drgcms_en.yml +17 -2
  78. data/config/locales/drgcms_sl.yml +20 -2
  79. data/config/locales/models_en.yml +7 -5
  80. data/config/locales/models_sl.yml +12 -9
  81. data/drg_cms.gemspec +16 -16
  82. data/lib/drg_cms/version.rb +1 -1
  83. data/lib/drg_cms.rb +94 -2
  84. metadata +32 -30
  85. data/app/models/__dc_dummy.rb +0 -102
@@ -1,4 +1,3 @@
1
- #coding: utf-8
2
1
  #--
3
2
  # Copyright (c) 2012+ Damjan Rems
4
3
  #
@@ -27,10 +26,10 @@
27
26
  # application controllers.
28
27
  ##########################################################################
29
28
  class DcApplicationController < ActionController::Base
30
- protect_from_forgery
31
-
32
- before_action :dc_reload_patches if Rails.env.development?
33
-
29
+ protect_from_forgery with: :null_session, only: Proc.new { |c| c.request.format.json? }
30
+ before_action :dc_reload_patches if Rails.env.development?
31
+ before_action :dc_set_locale
32
+
34
33
  ########################################################################
35
34
  # Writes anything passed as parameter to logger file.
36
35
  # Very useful for debuging strange errors.
@@ -55,9 +54,9 @@ end
55
54
  ####################################################################
56
55
  # Checks if user has required role.
57
56
  #
58
- # @param [DcPolicyRole] role can be passed as DcPolicyRole object or
59
- # @param [String] role as role name. If passed as name, dc_policy_roles is searched for appropriate role.
60
- #
57
+ # @param [DcPolicyRole or String] role can be passed as DcPolicyRole object or
58
+ # as role name. If passed as name, dc_policy_roles is searched for appropriate role.
59
+ #
61
60
  # @return [Boolean] True if user has required role added to his profile.
62
61
  #
63
62
  # @example If user has required role
@@ -66,8 +65,8 @@ end
66
65
  ####################################################################
67
66
  def dc_user_has_role(role)
68
67
  role = DcPolicyRole.get_role(role)
69
- return false if role.nil? or session[:user_roles].nil?
70
- # role is found in user_roles
68
+ return false if role.nil? || session[:user_roles].nil?
69
+ # role exists in user_roles
71
70
  session[:user_roles].include?(role._id)
72
71
  end
73
72
 
@@ -81,22 +80,28 @@ end
81
80
  # @example Returns Google analytics code from site settings
82
81
  # settings = dc_get_site.params['ga_acc']
83
82
  ####################################################################
84
- def dc_get_site()
85
- return @site if @site
83
+ def dc_get_site
84
+ return @site if @site
85
+
86
86
  uri = URI.parse(request.url)
87
+ cache_key = ['dc_site', uri.host]
88
+
89
+ @site = dc_cache_read(cache_key)
90
+ return @site if @site
91
+
87
92
  @site = DcSite.find_by(name: uri.host)
88
- # Site can be aliased
89
- if @site and !@site.alias_for.blank?
93
+ # Site can be aliased
94
+ if @site && !@site.alias_for.blank?
90
95
  @site = DcSite.find_by(name: @site.alias_for)
91
96
  end
92
- # Development environment. Check if site with name test exists and use
93
- # alias_for as pointer to real site.
94
- if @site.nil? and ENV["RAILS_ENV"] != 'production'
97
+ # Development environment. Check if site with name test exists and use
98
+ # alias_for as pointer to real site.
99
+ if @site.nil? && ENV["RAILS_ENV"] != 'production'
95
100
  @site = DcSite.find_by(name: 'test')
96
101
  @site = DcSite.find_by(name: @site.alias_for) if @site
97
- end
98
- @site = nil if @site and !@site.active # site is disabled
99
- @site
102
+ end
103
+ @site = nil if @site && !@site.active # site is disabled
104
+ dc_cache_write(cache_key, @site)
100
105
  end
101
106
 
102
107
  ##########################################################################
@@ -104,7 +109,7 @@ end
104
109
  #
105
110
  # Sets internal @page_title variable.
106
111
  ##########################################################################
107
- def set_page_title()
112
+ def set_page_title
108
113
  @page_title = @page.title.blank? ? @page.subject : @page.title
109
114
  dc_add_meta_tag(:name, 'description', @page.meta_description)
110
115
  end
@@ -115,18 +120,17 @@ end
115
120
  # @param [String] Form file name. File name can be passed as gem_name.filename. This can
116
121
  # be useful when you are extending form but want to retain same name as original form
117
122
  # For example. You are extending dc_user form from drg_cms gem and want to
118
- # retain same dc_user name. This can be done by setting drg_cms.dc_user to extend option.
123
+ # retain same dc_user name. This can be done by setting drg_cms.dc_user as extend option.
119
124
  #
120
125
  # @return [String] Form file name including path or nil if not found.
121
126
  ########################################################################
122
127
  def dc_find_form_file(form_file)
123
- form_path=nil
124
- if form_file.match(/\.|\//)
125
- form_path,form_file=form_file.split(/\.|\//)
126
- end
128
+ form_path = nil
129
+ form_path, form_file = form_file.split(/\.|\//) if form_file.match(/\.|\//)
130
+
127
131
  DrgCms.paths(:forms).reverse.each do |path|
128
132
  f = "#{path}/#{form_file}.yml"
129
- return f if File.exist?(f) and (form_path.nil? or path.to_s.match(/\/#{form_path}\//i))
133
+ return f if File.exist?(f) && (form_path.nil? || path.to_s.match(/\/#{form_path}(-|\/)/i))
130
134
  end
131
135
  raise "Exception: Form file '#{form_file}' not found!"
132
136
  end
@@ -149,7 +153,7 @@ end
149
153
  # Will write document to dc_visits collection unless visit comes from robot.
150
154
  # It also sets session[is_robot] variable to true if robot.
151
155
  ########################################################################
152
- def dc_log_visit()
156
+ def dc_log_visit
153
157
  if request.env["HTTP_USER_AGENT"] and request.env["HTTP_USER_AGENT"].match(/\(.*https?:\/\/.*\)/)
154
158
  logger.info "ROBOT: #{Time.now.strftime('%Y.%m.%d %H:%M:%S')} id=#{@page.id} ip=#{request.remote_ip}."
155
159
  session[:is_robot] = true
@@ -165,73 +169,79 @@ end
165
169
 
166
170
  protected
167
171
 
168
- #############################################################################
169
- # Add permissions. Subroutine of dc_user_can
170
- ############################################################################
171
- def __add_permissions_for(table_name=nil) # :nodoc:
172
- perm = table_name.nil? ? DcPermission.find_by(is_default: true) : DcPermission.find_by(table_name: table_name, active: true)
173
- (perm.dc_policy_rules.each {|p1| @permissions[p1.dc_policy_role_id] = p1.permission }) if perm
174
- end
175
-
176
- ############################################################################
172
+ ###########################################################################
177
173
  # Checks if user can perform (read, create, edit, delete) document in specified
178
174
  # table (collection).
179
175
  #
180
- # @param [Integer] Required permission level
181
- # @param [String] Collection (table) name for which permission is queried. Defaults to params[table].
176
+ # @param [Integer] permission: Required permission level
177
+ # @param [String] table: Collection (table) name for which permission is queried. Defaults to params[table].
182
178
  #
183
179
  # @return [Boolean] true if user's role permits (is higher or equal then required) operation on a table (collection).
184
180
  #
185
181
  # @Example True when user has view permission on the table
186
182
  # if dc_user_can(DcPermission::CAN_VIEW, params[:table]) then ...
187
183
  ############################################################################
188
- def __dc_user_can(permission, table=params[:table])
189
- if @permissions.nil?
190
- @permissions = {}
191
- add_permissions_for # default permission
192
- table_name = ''
193
- # permission can be set for table or object embedded in table. Read all possible values
194
- table.strip.downcase.split(';').each do |t|
195
- table_name << (table_name.size > 0 ? ';' : '') + t # table;embedded;another;...
196
- add_permissions_for table_name
197
- end
184
+ def dc_user_can(permission, table = params[:table])
185
+ table = table.underscore
186
+ cache_key = ['dc_permission', table, session[:user_id], dc_get_site.id]
187
+ permissions = dc_cache_read(cache_key)
188
+ if permissions.nil?
189
+ permissions = DcPermission.permissions_for_table(table)
190
+ dc_cache_write(cache_key, permissions)
198
191
  end
199
- # Return true if any of the permissions user has is higher or equal to requested permission
200
- session[:user_roles].each {|r| return true if @permissions[r] and @permissions[r] >= permission }
192
+ session[:user_roles].each { |r| return true if permissions[r] && permissions[r] >= permission }
201
193
  false
202
- end
194
+ end
203
195
 
204
- ###########################################################################
205
- # Checks if user can perform (read, create, edit, delete) document in specified
206
- # table (collection).
207
- #
208
- # @param [Integer] Required permission level
209
- # @param [String] Collection (table) name for which permission is queried. Defaults to params[table].
210
- #
211
- # @return [Boolean] true if user's role permits (is higher or equal then required) operation on a table (collection).
212
- #
213
- # @Example True when user has view permission on the table
214
- # if dc_user_can(DcPermission::CAN_VIEW, params[:table]) then ...
215
- ############################################################################
216
- def dc_user_can(permission, table=params[:table])
217
- @permissions ||= DcPermission.permissions_for_table(table)
218
- # Return true if any of the permissions user has is higher or equal to requested permission
219
- session[:user_roles].each {|r| return true if @permissions[r] and @permissions[r] >= permission }
220
- false
196
+ ####################################################################
197
+ # Read from cache
198
+ #
199
+ # @keys [Array] Array of keys
200
+ #
201
+ # @return [Object] Data returned from cache
202
+ ####################################################################
203
+ def dc_cache_read(keys)
204
+ if redis_cache_store?
205
+ keys = keys.dup
206
+ first = keys.shift
207
+ data = redis.hget(first, keys.join(''))
208
+ data ? Marshal.load(data) : nil
209
+ else
210
+ Rails.cache.read(keys.join(''))
211
+ end
221
212
  end
222
213
 
223
214
  ####################################################################
224
- # Detects if called from mobile agent according to http://detectmobilebrowsers.com/
215
+ # Write data to cache
216
+ #
217
+ # @param [Array] keys: Array of keys
218
+ # @param [Object] data: Data written to cache
219
+ #
220
+ # @return [Object] data so dc_cache_write can be used as last statement in method.
221
+ ####################################################################
222
+ def dc_cache_write(keys, data)
223
+ if redis_cache_store?
224
+ keys = keys.dup
225
+ first = keys.shift
226
+ redis.hset(first, keys.join(''), Marshal.dump(data))
227
+ else
228
+ Rails.cache.write(keys.join(''), data)
229
+ end
230
+ data
231
+ end
232
+
233
+ ####################################################################
234
+ # Detects if called from mobile agent according to http://detectmobilebrowsers.com/
225
235
  # and set session[:is_mobile]
226
- #
236
+ #
227
237
  # Detect also if caller is a robot and set session[:is_robot]
228
238
  ####################################################################
229
239
  def dc_set_is_mobile
230
240
  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])
231
241
  : false
232
242
  session[:is_mobile] = is_mobile ? 1 : 0
233
- #
234
- if request.env["HTTP_USER_AGENT"] and request.env["HTTP_USER_AGENT"].match(/\(.*https?:\/\/.*\)/)
243
+
244
+ if request.env["HTTP_USER_AGENT "] && request.env["HTTP_USER_AGENT"].match(/\(.*https?:\/\/.*\)/)
235
245
  logger.info "ROBOT: #{Time.now.strftime('%Y.%m.%d %H:%M:%S')} id=#{@page.id} ip=#{request.remote_ip}."
236
246
  session[:is_robot] = true
237
247
  end
@@ -240,23 +250,13 @@ end
240
250
  ##########################################################################
241
251
  # Merge values from parameters fields (from site, page ...) into internal @options hash.
242
252
  #
243
- # @param [String] YAML string.
253
+ # @param [String] parameters: passed as YAML string.
244
254
  ##########################################################################
245
255
  def dc_set_options(parameters)
246
256
  @options ||= {}
247
257
  return if parameters.to_s.size < 3
248
- # parameters are set az YAML. This should be default in future.
249
- parms = YAML.load(parameters) rescue nil
250
- if parms.nil? # error when loadnig yaml, try the old way parsing manually
251
- parms = {}
252
- parameters.split("\n").each do |line|
253
- line.chomp.split(',').each do |parm|
254
- key, value = parm.split(':')
255
- value = value.to_s.strip.gsub(/\'|\"/,'')
256
- parms[key.strip] = (value == '/' ? nil : value)
257
- end
258
- end
259
- end
258
+ # parameters are set as YAML. This should be default in future.
259
+ parms = YAML.load(parameters) rescue {}
260
260
  @options.merge!(parms)
261
261
  end
262
262
 
@@ -270,7 +270,6 @@ end
270
270
  # @return [Boolean] true when none of documents is changed.
271
271
  ##########################################################################
272
272
  def dc_not_modified?(*documents)
273
- # request.env.each {|k,v| p k,'*',v}
274
273
  return false unless request.env.include? 'HTTP_IF_MODIFIED_SINCE'
275
274
 
276
275
  since_date = Time.parse request.env['HTTP_IF_MODIFIED_SINCE']
@@ -279,7 +278,7 @@ def dc_not_modified?(*documents)
279
278
  next unless doc.respond_to?(:updated_at)
280
279
  last_modified = doc.updated_at if doc.updated_at > last_modified
281
280
  end
282
- # p last_modified, since_date
281
+
283
282
  if last_modified >= since_date then
284
283
  render :nothing => true, :status => 304
285
284
  return true
@@ -298,16 +297,16 @@ def get_design_and_render(design_doc)
298
297
  layout = @site.site_layout.blank? ? 'content' : @site.site_layout
299
298
  site_top = '<%= dc_page_top %>'
300
299
  site_bottom = '<%= dc_page_bottom %>'
301
- # lets try the rails way
302
- if @options[:control] and @options[:action]
300
+ # lets try the rails way
301
+ if @options[:control] && @options[:action]
303
302
  controller = "#{@options[:control]}_control".classify.constantize rescue nil
304
303
  extend controller if controller
305
304
  return send @options[:action] if respond_to?(@options[:action])
306
305
  end
307
- # design doc present
306
+ # design doc present
308
307
  if design_doc
309
308
  # defined as rails view
310
- design = if design_doc.rails_view.blank? or design_doc.rails_view == 'site'
309
+ design = if design_doc.rails_view.blank? || design_doc.rails_view == 'site'
311
310
  @site.rails_view
312
311
  else
313
312
  design_doc.rails_view
@@ -318,8 +317,8 @@ def get_design_and_render(design_doc)
318
317
  design = site_top + design + site_bottom
319
318
  return render(inline: design, layout: layout) unless design.blank?
320
319
  end
321
- # Design doc not defined
322
- if @site.rails_view.blank?
320
+ # Design doc not defined
321
+ if @site.rails_view.blank?
323
322
  design = site_top + @site.design + site_bottom
324
323
  render(inline: design, layout: layout)
325
324
  else
@@ -341,34 +340,35 @@ end
341
340
  # dc_process_default_request
342
341
  # end
343
342
  ##########################################################################
344
- def dc_process_default_request()
343
+ def dc_process_default_request
345
344
  session[:edit_mode] ||= 0
346
- # Initialize parts
345
+ # Initialize parts
347
346
  @parts = nil
348
347
  @js, @css = '', ''
349
- # find domain name in sites
348
+ # find domain name in sites
350
349
  @site = dc_get_site
351
- # site not defined. render 404 error
350
+ # site not defined. render 404 error
352
351
  return dc_render_404('Site!') if @site.nil?
352
+
353
353
  dc_set_options(@site.settings)
354
- # HOMEPAGE. When no parameters is set
354
+ # HOMEPAGE. When no parameters is set
355
355
  params[:path] = @site.homepage_link if params[:id].nil? and params[:path].nil?
356
356
  @options[:path] = params[:path].to_s.downcase.split('/')
357
357
  params[:path] = @options[:path].first if @options[:path].size > 1
358
- # some other process request. It should fail if not defined
358
+ # some other process request. It should fail if not defined
359
359
  return send(@site.request_processor) unless @site.request_processor.blank?
360
360
 
361
- # Search for page
361
+ # Search for page
362
362
  pageclass = @site.page_klass
363
363
  if params[:id]
364
364
  #Page.where(id: params[:id]).or(subject_link: params[:id]).first
365
365
  @page = pageclass.find_by(:dc_site_id.in => [@site._id, nil], subject_link: params[:id], active: true)
366
366
  @page = pageclass.find(params[:id]) if @page.nil? # I think that there will be more subject_link searchers than id
367
367
  elsif params[:path]
368
- # path may point direct to page's subject_link
368
+ # path may point direct to page's subject_link
369
369
  @page = pageclass.find_by(:dc_site_id.in => [@site._id, nil], subject_link: params[:path], active: true)
370
370
  if @page.nil?
371
- # no. Find if defined in links
371
+ # no. Find if defined in links
372
372
  link = DcLink.find_by(:dc_site_id.in => [@site._id, nil], name: params[:path])
373
373
  if link
374
374
  #pageclass.find_by(alt_link: params[:path])
@@ -377,10 +377,11 @@ def dc_process_default_request()
377
377
  end
378
378
  end
379
379
  end
380
- # if @page is not found render 404 error
380
+ # if @page is not found render 404 error
381
381
  return dc_render_404('Page!') unless @page
382
+
382
383
  dc_set_is_mobile unless session[:is_mobile] # do it only once per session
383
- # find design if defined. Otherwise design MUST be declared in site
384
+ # find design if defined. Otherwise design MUST be declared in site
384
385
  if @page.dc_design_id
385
386
  @design = DcDesign.find(@page.dc_design_id)
386
387
  return dc_render_404('Design!') unless @design
@@ -388,20 +389,20 @@ def dc_process_default_request()
388
389
  dc_set_options @design.params if @design
389
390
  dc_set_options @page.params
390
391
  dc_add_json_ld(@page.get_json_ld)
391
- # Add edit menu
392
+ # Add edit menu
392
393
  if session[:edit_mode] > 0
393
394
  session[:site_id] = @site.id
394
395
  session[:site_page_class] = @site.page_class
395
396
  session[:page_id] = @page.id
396
- else
397
- # Log only visits from non-editors
397
+ else
398
+ # Log only visits from non-editors
398
399
  dc_log_visit()
399
400
  end
400
401
  set_page_title()
401
402
  get_design_and_render @design
402
403
  end
403
404
 
404
- ##########################################################################
405
+ ###########################################################################
405
406
  # Single site document kind of request handler.
406
407
  #
407
408
  # This request handler assumes that all data for the site is saved in the site document.
@@ -417,18 +418,17 @@ def dc_single_sitedoc_request
417
418
  if @site.nil?
418
419
  session[:edit_mode] ||= 0
419
420
  @site = dc_get_site
420
- # @site is not defined. render 404 error
421
+ # @site is not defined. render 404 error
421
422
  return dc_render_404('Site!') unless @site
423
+
422
424
  dc_set_options(@site.settings)
423
425
  end
424
- # HOMEPAGE. When no parameters is set
426
+ # HOMEPAGE. When no parameters is set
425
427
  params[:path] = @site.homepage_link if params[:path].nil?
426
428
  @parts = @site.dc_parts
427
429
  @part = @parts.find_by(link: params[:path])
428
430
  return dc_render_404('Part!') unless @part
429
- # Document was not modified since last visit
430
- # return if dc_not_modified?(@site, @part)
431
- #
431
+
432
432
  @page_title = "#{@site.page_title} #{@part.name}"
433
433
  @js, @css = '', ''
434
434
  get_design_and_render nil
@@ -439,46 +439,36 @@ end
439
439
  # very good with non ascii chars. Since this method is used for converting from model
440
440
  # to collection names it is very unwise to use non ascii chars for table (collection) names.
441
441
  #
442
- # @param [String] String to be converted
443
- #
442
+ # @param [Object] model_string to be converted
443
+ #
444
444
  # @example
445
445
  # decamelize_type(ModelName) # 'ModelName' => 'model_name'
446
446
  ########################################################################
447
- def decamelize_type(string)
448
- return nil unless string
449
- r = ''
450
- string.to_s.each_char do |c|
451
- r << case
452
- when r.size == 0 then c.downcase
453
- when c.downcase != c then '_' + c.downcase
454
- else c
455
- end
456
- end
457
- r
447
+ def decamelize_type(model_string)
448
+ model_string ? model_string.underscore : nil
458
449
  end
459
450
 
460
451
  ####################################################################
461
452
  # Return's error messages for the document formated for display on edit form.
462
453
  #
463
- # @param [Document] Document object which will be examined for errors.
464
- #
454
+ # @param [Document] document object which will be examined for errors.
455
+ #
465
456
  # @return [String] HTML code for displaying error on edit form.
466
457
  ####################################################################
467
458
  def dc_error_messages_for(document)
468
459
  return '' unless document.errors.any?
460
+
469
461
  msg = ''
470
- document.errors.each do |attribute, errors_array|
471
- label = t("helpers.label.#{decamelize_type(document.class)}.#{attribute}")
472
- msg << "<li>#{label} : #{errors_array}</li>"
462
+ document.errors.each do |error|
463
+ label = t("helpers.label.#{decamelize_type(document.class)}.#{error.attribute}", error.attribute)
464
+ msg << "<li>#{label} : #{error.message}</li>"
473
465
  end
474
466
 
475
- html = <<eot
467
+ %(
476
468
  <div class="dc-form-error">
477
469
  <h2>#{t('drgcms.errors_no')} #{document.errors.size}</h2>
478
470
  <ul>#{msg}</ul>
479
- </div>
480
- eot
481
- html.html_safe
471
+ </div>).html_safe
482
472
  end
483
473
 
484
474
  ####################################################################
@@ -487,8 +477,8 @@ end
487
477
  # model errors or when saving to multiple collections and where each save must be
488
478
  # checked if succesfull.
489
479
  #
490
- # @param [Document] Document object which will be checked
491
- # @param [Boolean] If true method should end in runtime error. Default = false.
480
+ # @param [Document] document: Document object to be checked
481
+ # @param [Boolean] crash: If true method should end in runtime error. Default = false.
492
482
  #
493
483
  # @return [String] Error messages or empty string if everything is OK.
494
484
  #
@@ -500,16 +490,16 @@ end
500
490
  # end
501
491
  #
502
492
  ####################################################################
503
- def dc_check_model(document, crash=false)
504
- DcApplicationController.dc_check_model(document, crash=false)
493
+ def dc_check_model(document, crash = false)
494
+ DrgCms.model_check(document, crash)
505
495
  end
506
496
 
507
497
  ######################################################################
508
498
  # Call rake task from controller.
509
499
  #
510
- # @param [String] Rake task name
511
- # @param [Hash] Options that will be send to task as environment variables
512
- #
500
+ # @param [String] task: Rake task name
501
+ # @param [Hash] options: Options that will be send to task as environment variables
502
+ #
513
503
  # @example Call rake task from application
514
504
  # dc_call_rake('clear:all', some_parm: some_id)
515
505
  ######################################################################
@@ -524,8 +514,8 @@ end
524
514
  # made from DRG CMS form return may be quite complicated. All ajax return combinations
525
515
  # can be found in drg_cms.js file.
526
516
  #
527
- # @param [Hash] Options
528
- #
517
+ # @param [Hash] opts: Options
518
+ #
529
519
  # @return [JSON Response] Formatted to be used for ajax return.
530
520
  #
531
521
  # @example
@@ -537,7 +527,7 @@ end
537
527
  ######################################################################
538
528
  def dc_render_ajax(opts)
539
529
  result = {}
540
- if opts[:div] or opts[:class]
530
+ if opts[:div] || opts[:class]
541
531
  selector = opts[:div] ? '#' : '.' # for div . for class
542
532
  key = case
543
533
  when opts[:prepend] then "#{selector}+div"
@@ -559,7 +549,7 @@ end
559
549
  # @param [String] Table (collection) name. Could be dc_page;dc_part;... when searching for embedded document.
560
550
  # @param [String] Id of the document
561
551
  # @param [String] Ids of parent documents when document is embedded. Ids are separated by ; char.
562
- #
552
+ #
563
553
  # @return [document]. Required document or nil if not found.
564
554
  #
565
555
  # @example As used in Cmsedit_controller
@@ -589,6 +579,20 @@ def dc_reload_patches
589
579
  end
590
580
  end
591
581
 
582
+ ########################################################################
583
+ # Will set new default locale for application
584
+ #
585
+ # @param [String] new_locale : New locale value. If omitted it will be provided from params[:locale].
586
+ # if new_locale value is 00, application's default_locale will be used.
587
+ ########################################################################
588
+ def dc_set_locale(new_locale = nil)
589
+ new_locale ||= params[:locale]
590
+ if new_locale && new_locale != session[:locale]
591
+ session[:locale] = new_locale == '00' ? nil : new_locale.to_sym
592
+ end
593
+ I18n.locale = session[:locale] ? session[:locale] : I18n.default_locale
594
+ end
595
+
592
596
  ############################################################################
593
597
  # Writes out deprication msg. It also adds site_name to message, so it is easier to
594
598
  # find where the message is comming from.
@@ -604,7 +608,7 @@ def clear_login_data
604
608
  session[:edit_mode] = 0
605
609
  session[:user_id] = nil
606
610
  session[:user_name] = nil
607
- session[:user_roles] = nil
611
+ set_default_guest_user_role
608
612
  cookies.delete :remember_me
609
613
  end
610
614
 
@@ -622,32 +626,48 @@ end
622
626
  # @param [DcUser] user : User's document
623
627
  # @param [Boolean] remember_me : false by default
624
628
  ####################################################################
625
- def fill_login_data(user, remember_me=false)
626
- session[:user_id] = user.id if user
627
- session[:user_name] = user.name if user
628
- session[:edit_mode] = 0
629
- session[:user_roles] = []
630
- # Every user has guest role
631
- # guest = DcPolicyRole.find_by(system_name: 'guest')
632
- # session[:user_roles] << guest.id if guest
629
+ def fill_login_data(user, remember_me = false)
630
+ session[:user_id] = user.id if user
631
+ session[:user_name] = user.name.squish if user
632
+ session[:edit_mode] = 0
633
633
  set_default_guest_user_role
634
- return unless user and user.active
634
+ return unless user&.active
635
+
635
636
  # special for SUPERADMIN
636
637
  sa = DcPolicyRole.find_by(system_name: 'superadmin')
637
- if sa and (role = user.dc_user_roles.find_by(dc_policy_role_id: sa.id))
638
+ if sa && (role = user.dc_user_roles.find_by(dc_policy_role_id: sa.id))
638
639
  session[:user_roles] << role.dc_policy_role_id
639
- session[:edit_mode] = 2
640
+ session[:edit_mode] = 2
640
641
  return
641
642
  end
642
- # read default policy from site. Policy might be inherited
643
+ # read default policy from site. Policy might be inherited from other site
643
644
  policy_site = dc_get_site()
644
645
  policy_site = DcSite.find(policy_site.inherit_policy) if policy_site.inherit_policy
645
646
  default_policy = policy_site.dc_policies.find_by(is_default: true)
646
- # load user roles
647
+
648
+ # load user roles from groups
649
+ roles = {}
650
+ user.member.each do |group_id|
651
+ group = DcUser.find(group_id)
652
+ next unless group.active
653
+
654
+ group.dc_user_roles.each do |role|
655
+ next unless role.active?
656
+ roles[role.dc_policy_role_id] = role
657
+ end
658
+ end unless user.member.blank?
659
+
660
+ # load user roles from user
647
661
  user.dc_user_roles.each do |role|
648
- next unless role.active
649
- next if role.valid_from and role.valid_from > Time.now.end_of_day.to_date
650
- next if role.valid_to and role.valid_to < Time.now.to_date
662
+ # not active in user roles will remove role defined in groups
663
+ unless role.active?
664
+ roles.delete(role.dc_policy_role_id) if roles[role.dc_policy_role_id]
665
+ next
666
+ end
667
+ roles[role.dc_policy_role_id] = role
668
+ end
669
+ # select only roles defined in default site policy and set edit_mode
670
+ roles.each do |key, role|
651
671
  # check if role is active in this site
652
672
  policy_role = default_policy.dc_policy_rules.find_by(dc_policy_role_id: role.dc_policy_role_id)
653
673
  next unless policy_role
@@ -656,20 +676,19 @@ def fill_login_data(user, remember_me=false)
656
676
  session[:user_roles] << role.dc_policy_role_id
657
677
  end
658
678
  # Save remember me cookie if not CMS user and remember me is selected
659
- if session[:edit_mode] == 0 and remember_me
660
- cookies.signed[:remember_me] = { :value => user.id, :expires => 180.days.from_now}
679
+ if session[:edit_mode] == 0 && remember_me
680
+ cookies.signed[:remember_me] = { value: user.id, expires: 180.days.from_now }
661
681
  end
662
682
  end
663
683
 
664
684
  ##########################################################################
665
- # Will check if user's login data is stil valid and reload user roles.
685
+ # Will check if user's login data is still valid and reload user roles.
666
686
  #
667
687
  # @param [Time] repeat_after : Check is repeated after time. This is by default performed every 24 hours.
668
688
  ##########################################################################
669
- def dc_check_user_still_valid(repeat_after=1.day)
670
- # not needed
671
- return if session[:user_id].nil?
672
- # last check more than a day ago
689
+ def dc_check_user_still_valid(repeat_after = 1.day)
690
+ return if session[:user_id].nil?
691
+ # last check more than repeat_after ago
673
692
  if (session[:user_chk] ||= Time.now) < repeat_after.ago
674
693
  user_id = session[:user_id]
675
694
  clear_login_data
@@ -684,9 +703,9 @@ end
684
703
  # Evaluates Class.method in more predictable context then just calling eval
685
704
  #
686
705
  # @param [String] class_method defined as MyClass.method_name
687
- # @param [Object] optional parameters send to class_method
706
+ # @param [Object] params: optional parameters send to class_method
688
707
  ##########################################################################
689
- def dc_eval_class_method(class_method, params=nil)
708
+ def dc_eval_class_method(class_method, params = nil)
690
709
  klass, method = class_method.split('.')
691
710
  # check if class exists
692
711
  klass = klass.classify.constantize rescue nil
@@ -729,25 +748,33 @@ end
729
748
  ########################################################################
730
749
  def dc_add_meta_tag(type, name, content)
731
750
  return if content.blank?
751
+
732
752
  @meta_tags ||= {}
733
753
  key = "#{type}=\"#{name}\""
734
754
  @meta_tags[key] = content
735
755
  end
736
756
 
737
757
  ########################################################################
738
- # Will prepare flash[:update] data, which will be used for updating fields
739
- # on forms parent form fields.
740
- #
741
- # Parameters:
742
- # [field_name] String: Field name
758
+ # Will prepare flash[:update] data, which is used for updating elements
759
+ # on parent form.
760
+ #
761
+ # Parameters passed as hash:
762
+ # [field] String: Field name
763
+ # [head] String: Filed name in head of form
743
764
  # [value] String: New value
744
765
  # [readonly] Boolean: Field is readonly
745
- #
766
+ #
746
767
  ########################################################################
747
- def dc_update_form_field(field_name, value, readonly=false)
748
- key_name = (readonly ? 'td_' : '') + "record_#{field_name}"
768
+ def dc_update_form_element(field: nil, head: nil, value:, readonly: true)
769
+ key = if field
770
+ (readonly ? 'td_' : '') + "record_#{field}"
771
+ elsif head
772
+ "head-#{head}"
773
+ end
774
+ return if key.nil?
775
+
749
776
  flash[:update] ||= {}
750
- flash[:update][key_name] = value
777
+ flash[:update][key] = value
751
778
  end
752
779
 
753
780
  ####################################################################
@@ -769,20 +796,8 @@ end
769
796
  # end
770
797
  #
771
798
  ####################################################################
772
- def self.dc_check_model(document, crash=false)
773
- return nil unless document.errors.any?
774
- msg = ""
775
- document.errors.each do |attribute, errors_array|
776
- msg << "#{attribute}: #{errors_array}\n"
777
- end
778
- #
779
- if crash and msg.size > 0
780
- msg = "Validation errors in #{document.class}:\n" + msg
781
- pp msg
782
- Rails.logger.error(msg)
783
- raise "Validation error. See log for more information."
784
- end
785
- msg
799
+ def self.dc_check_model(document, crash = false)
800
+ DrgCms.model_check(document, crash)
786
801
  end
787
802
 
788
803
  ########################################################################
@@ -798,5 +813,24 @@ def dc_dump_exception(exception)
798
813
  Rails.logger.error msg
799
814
  end
800
815
 
816
+ private
817
+
818
+ ########################################################################
819
+ # Determines if redis cache store is active
820
+ #
821
+ # @return [Boolean] : True if redis cache store is active
822
+ ########################################################################
823
+ def redis_cache_store?
824
+ (Rails.application.config.cache_store.first == :redis_cache_store) rescue false
825
+ end
826
+
827
+ ########################################################################
828
+ # Returns redis object
829
+ #
830
+ # @return [Object] : Redis object
831
+ ########################################################################
832
+ def redis
833
+ Rails.cache.redis
834
+ end
801
835
 
802
836
  end