drg_cms 0.6.1.11 → 0.7.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +260 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +9 -5
  5. data/app/assets/javascripts/drg_cms/drg_cms.js +95 -34
  6. data/app/assets/javascripts/drg_cms/jquery.bpopup.js +372 -0
  7. data/app/assets/javascripts/drg_cms_application.js +1 -3
  8. data/app/assets/javascripts/drg_cms_cms.js +3 -4
  9. data/app/assets/stylesheets/drg_cms/drg_cms.css +37 -5
  10. data/app/assets/stylesheets/drg_cms/jstree.css +32 -27
  11. data/app/assets/stylesheets/drg_cms/select-multiple.css +6 -4
  12. data/app/controllers/cmsedit_controller.rb +22 -24
  13. data/app/controllers/dc_application_controller.rb +10 -9
  14. data/app/controllers/dc_common_controller.rb +14 -11
  15. data/app/controllers/dc_main_controller.rb +0 -1
  16. data/app/controls/dc_gallery_control.rb +46 -0
  17. data/app/controls/dc_image_control.rb +180 -0
  18. data/app/controls/dc_page_control.rb +3 -3
  19. data/app/controls/dc_poll_result_control.rb +7 -8
  20. data/app/controls/dc_report.rb +9 -4
  21. data/app/controls/design_element_settings_control.rb +88 -37
  22. data/app/forms/all_options.yml +18 -7
  23. data/app/forms/cms_menu.yml +10 -4
  24. data/app/forms/dc_category.yml +17 -8
  25. data/app/forms/dc_category_as_tree.yml +31 -0
  26. data/app/forms/dc_gallery.yml +1 -1
  27. data/app/forms/dc_image.yml +122 -0
  28. data/app/forms/dc_image_search.yml +72 -0
  29. data/app/forms/dc_page.yml +11 -8
  30. data/app/forms/dc_steps_template.yml +2 -1
  31. data/app/forms/help/dc_category_as_tree.en +4 -0
  32. data/app/forms/help/dc_category_as_tree.sl +5 -0
  33. data/app/helpers/cms_common_helper.rb +24 -16
  34. data/app/helpers/cms_edit_helper.rb +28 -35
  35. data/app/helpers/cms_helper.rb +21 -5
  36. data/app/helpers/cms_index_helper.rb +53 -38
  37. data/app/helpers/dc_application_helper.rb +95 -121
  38. data/app/helpers/dc_category_helper.rb +129 -0
  39. data/app/helpers/dc_image_helper.rb +127 -0
  40. data/app/models/concerns/dc_policy_rule_concern.rb +1 -1
  41. data/app/models/concerns/dc_user_concern.rb +12 -4
  42. data/app/models/dc_category.rb +62 -24
  43. data/app/models/dc_design.rb +5 -4
  44. data/app/models/dc_filter.rb +19 -18
  45. data/app/models/dc_image.rb +237 -0
  46. data/app/models/dc_internals.rb +5 -9
  47. data/app/models/dc_policy_role.rb +8 -8
  48. data/app/models/drgcms_form_fields/date_picker.rb +10 -12
  49. data/app/models/drgcms_form_fields/datetime_picker.rb +10 -11
  50. data/app/models/drgcms_form_fields/drgcms_field.rb +55 -30
  51. data/app/models/drgcms_form_fields/embedded.rb +11 -8
  52. data/app/models/drgcms_form_fields/journal_diff.rb +2 -2
  53. data/app/models/drgcms_form_fields/multitext_autocomplete.rb +51 -47
  54. data/app/models/drgcms_form_fields/select.rb +20 -14
  55. data/app/models/drgcms_form_fields/text_with_select.rb +5 -9
  56. data/app/models/drgcms_form_fields/tree_select.rb +20 -19
  57. data/app/renderers/dc_gallery_renderer.rb +10 -4
  58. data/app/renderers/dc_page_renderer.rb +7 -7
  59. data/app/renderers/dc_poll_renderer.rb +13 -12
  60. data/app/views/cmsedit/_edit_stuff.html.erb +1 -1
  61. data/app/views/cmsedit/edit.html.erb +1 -1
  62. data/app/views/cmsedit/index.html.erb +1 -1
  63. data/app/views/cmsedit/new.html.erb +1 -0
  64. data/app/views/layouts/content.html.erb +1 -1
  65. data/config/locales/drgcms_en.yml +16 -2
  66. data/config/locales/drgcms_sl.yml +15 -2
  67. data/config/locales/models_en.yml +33 -0
  68. data/config/locales/models_sl.yml +44 -1
  69. data/drg_cms.gemspec +3 -3
  70. data/lib/drg_cms/version.rb +1 -1
  71. data/lib/drg_cms.rb +19 -5
  72. data/lib/generators/convert_to_ar/USAGE +8 -0
  73. data/lib/generators/convert_to_ar/convert_to_ar_generator.rb +158 -0
  74. data/lib/tasks/dc_cleanup.rake +20 -42
  75. metadata +25 -14
  76. data/History.log +0 -109
  77. data/app/assets/javascripts/drg_cms/jquery.bpopup.min.js +0 -7
  78. data/app/views/layouts/__cmsedit.html.erb +0 -16
@@ -0,0 +1,127 @@
1
+ #--
2
+ # Copyright (c) 2022+ 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
+ ####################################################################
26
+ # Helpers needed by some form fields
27
+ ####################################################################
28
+ module DcImageHelper
29
+
30
+ ############################################################################
31
+ # Will return code for previewing image on top of dc_image entry form
32
+ ############################################################################
33
+ def dc_image_preview(document, *parms)
34
+ src = "/#{dc_get_site.params.dig('dc_image', 'location')}/#{document.first_available_image}"
35
+ %(<span class="dc-image-preview dc-image-preview-1"><img src="#{src}"></img></span>).html_safe
36
+ end
37
+
38
+ ############################################################################
39
+ # Will return code for previewing resized images on dc_image entry form
40
+ ############################################################################
41
+ def dc_image_preview_resized(document, yaml, ignore)
42
+ size = yaml['name'].last
43
+ return '' if document["size_#{size}"].blank?
44
+
45
+ src = "/#{dc_get_site.params.dig('dc_image', 'location')}/#{document.id}-#{size}.#{document.img_type}?#{Time.now.to_i}"
46
+ %(<span class="dc-image-preview"><img src="#{src}"></img></span><div id="dc-image-preview"></div>).html_safe
47
+ end
48
+
49
+ ############################################################################
50
+ # Will return choices for preset image sizes
51
+ ############################################################################
52
+ def dc_image_choices_for_image_size
53
+ sizes = dc_get_site.params.dig('dc_image', 'sizes')
54
+ return ['300x200'] if sizes.blank?
55
+
56
+ sizes.split(",").map(&:strip)
57
+ end
58
+
59
+ ############################################################################
60
+ # Will return code for invoking dc_image_search form to select image select on a DRG Form.
61
+ #
62
+ # @param [String] field_name : Field name to which selected image value will be saved.
63
+ ###########################################################################
64
+ def dc_image_invoke(field_name)
65
+ return '' unless dc_get_site.params.dig('dc_image', 'location')
66
+
67
+ url = url_for(controller: :cmsedit, form_name: :dc_image_search, table: :dc_image, field_name: field_name)
68
+ %(<span class="dc-window-open" data-url="#{url}" title="#{t('drgcms.dc_image.invoke')}">#{mi_icon('image-o')}</span>).html_safe
69
+ end
70
+
71
+ ############################################################################
72
+ # Will return code for previewing image on top of dc_image entry form
73
+ ############################################################################
74
+ def dc_image_first(document, *parms)
75
+ src = "/#{dc_get_site.params.dig('dc_image', 'location')}/#{document.first_available_image}"
76
+ %(<span class="dc-image-preview"><img src="#{src}"></img></span><span id="dc-image-preview">).html_safe
77
+ end
78
+
79
+ ######################################################################
80
+ # Will format qry result as html code for selecting image
81
+ ######################################################################
82
+ def dc_image_select_links(doc, *parms)
83
+ %w[o s m l].inject('') { | r,size| r << dc_image_link_for_select(doc, size) }.html_safe
84
+ end
85
+
86
+ ######################################################################
87
+ # Will return HTML code for selecting image
88
+ ######################################################################
89
+ def dc_image_link_for_select(doc, what)
90
+ field = "size_#{what}"
91
+ value = doc.send(field)
92
+ return '' if value.blank?
93
+
94
+ value = value.split(/\+/).first
95
+ src = "/#{dc_get_site.params.dig('dc_image', 'location')}/#{doc.id}-#{what}.#{doc.img_type}"
96
+ %(
97
+ <div class="img-link"><div>
98
+ #{value}<br>
99
+ <i class="mi-o mi-preview" onclick="dc_image_preview('#{src}');" title="#{t('drgcms.dc_image.preview')}"></i>
100
+ <i class="mi-o mi-check_circle" onclick="dc_image_select('#{src}');" title="#{t('drgcms.dc_image.select')}"></i>
101
+ </div></div>)
102
+ end
103
+
104
+ ######################################################################
105
+ # Will return image file for requested size.
106
+ #
107
+ # @param [String] file_name : Image file name
108
+ # @param [String] size : Preferred image size
109
+ #
110
+ # @return [String] : Image file name if requested size is found. Otherwise first available image.
111
+ ######################################################################
112
+ def dc_image_get_by_size(file_name, size)
113
+ id = file_name[file_name.rindex('/') + 1, 24]
114
+ return 'error: ID not valid' unless BSON::ObjectId.legal?(id)
115
+
116
+ image = DcImage.find(id)
117
+ return 'error: ID not found' unless image
118
+
119
+ what = %w[o s m l].inject('l') do |r, e|
120
+ field_name = "size_#{e}".to_sym
121
+ break e if doc.send(field_name) == size
122
+ e
123
+ end
124
+ "/#{dc_get_site.params.dig('dc_image', 'location')}/#{doc.id}-#{what}.#{doc.img_type}"
125
+ end
126
+
127
+ end
@@ -52,7 +52,7 @@ after_destroy :cache_clear
52
52
  def self.values_for_permissions
53
53
  key = 'helpers.label.dc_policy_rule.choices4_permission'
54
54
  c = I18n.t(key)
55
- c = I18n.t(key, locale: 'en') if c.class == Hash or c.match( 'translation missing' )
55
+ c = I18n.t(key, locale: 'en') if c.class == Hash || c.match(/translation missing/i)
56
56
  c.split(',').inject([]) { |r,e| r << (ar = e.split(':'); [ar.first, ar.last.to_i]) }
57
57
  end
58
58
 
@@ -80,7 +80,7 @@ index group: 1
80
80
  validates_length_of :username, minimum: 4
81
81
  validates :username, uniqueness: true
82
82
  validates :email, uniqueness: true
83
- validate :do_validate
83
+ validate :additional_validates
84
84
 
85
85
  before_save :do_before_save
86
86
  before_validation :do_before_validation
@@ -97,8 +97,16 @@ def has_role?(role_id)
97
97
  role = DcPolicyRole.get_role(role_id)
98
98
  role_id = role.id if role
99
99
  end
100
- role = self.dc_user_roles.where(dc_policy_role_id: role_id).first
101
- (role && role.active)
100
+ role = dc_user_roles.find_by(dc_policy_role_id: role_id)
101
+
102
+ # user can be member of groups
103
+ if role.nil? && member.present?
104
+ member.each do |group_id|
105
+ role = DrgCms.cached(DcUser, group_id).dc_user_roles.find_by(dc_policy_role_id: role_id)
106
+ break if role
107
+ end
108
+ end
109
+ role&.active?
102
110
  end
103
111
 
104
112
  ##########################################################################
@@ -169,7 +177,7 @@ end
169
177
  ##########################################################################
170
178
  # Perform some additional validations
171
179
  ##########################################################################
172
- def do_validate
180
+ def additional_validates
173
181
  if group && member.present?
174
182
  errors.add('member', I18n.t('errors.messages.present'))
175
183
  end
@@ -42,32 +42,72 @@
42
42
  # is most useful for grouping news, blog entries ...
43
43
  #####################################################################
44
44
  class DcCategory
45
- include Mongoid::Document
46
- include Mongoid::Timestamps
45
+ include Mongoid::Document
46
+ include Mongoid::Timestamps
47
47
 
48
- field :name, type: String
49
- field :description, type: String
50
- field :ctype, type: Integer, default: 1
51
- field :parent, type: BSON::ObjectId
52
- field :active, type: Boolean, default: true
53
- field :order, type: Integer, default: 0
54
- field :created_by, type: BSON::ObjectId
55
- field :updated_by, type: BSON::ObjectId
56
- field :dc_site_id, type: BSON::ObjectId
48
+ field :name, type: String
49
+ field :description, type: String
50
+ field :ctype, type: Integer, default: 1
51
+ field :parent, type: BSON::ObjectId
52
+ field :active, type: Boolean, default: true
53
+ field :order, type: Integer, default: 0
54
+ field :created_by, type: BSON::ObjectId
55
+ field :updated_by, type: BSON::ObjectId
56
+ field :dc_site_id, type: BSON::ObjectId
57
57
 
58
- validates :name, :presence => true
59
-
60
- index name: 1
61
- index ctype: 1
62
- index site_id: 1
58
+ index name: 1
59
+ index ctype: 1
60
+ index site_id: 1
61
+
62
+ validates :name, presence: true
63
+
64
+ before_destroy :can_destroy?
65
+
66
+ after_save :cache_clear
67
+ after_destroy :cache_clear
68
+
69
+ ####################################################################
70
+ # Clear cache if cache is configured
71
+ ####################################################################
72
+ def cache_clear
73
+ DrgCms.cache_clear(:dc_category)
74
+ end
75
+
76
+ private
77
+
78
+ #########################################################################
79
+ # Can't delete if category document has children documents
80
+ #########################################################################
81
+ def can_destroy?
82
+ if DcCategory.where(parent: id).count > 0
83
+ errors.add(:base, I18n.t('drgcms.category_has_subs'))
84
+ throw :abort
85
+ end
86
+ end
63
87
 
64
88
  #########################################################################
65
- # Returns all values vhich can be used as parent select field.
89
+ # Returns all values for use as parent select field.
66
90
  #########################################################################
67
- def self.values_for_parent(site_id=nil) #:nodoc:
91
+ def self.values_for_parent(site_id = nil) #:nodoc:
68
92
  qry = where(active: true)
69
93
  qry = qry.and(dc_site_id: site_id.id) if site_id
70
- qry.sort(name: 1).inject([]) {|r,v| r << [v.name, v._id]}
94
+ parents = {} # cache parent names to minimize database usage
95
+ qry.inject([]) do |r, v|
96
+ if parents[v.parent].nil?
97
+ name = ''
98
+ parent = v.parent
99
+ until parent.nil?
100
+ doc = find(parent)
101
+ break if doc.nil?
102
+
103
+ name = doc.name + ' / ' + name
104
+ parent = doc.parent
105
+ end
106
+ parents[v.parent] = name
107
+ end
108
+ name = v.parent ? parents[v.parent] + v.name : v.name
109
+ r << [name, v._id]
110
+ end.sort { |a, b| a.first <=> b.first }
71
111
  end
72
112
 
73
113
  #########################################################################
@@ -80,8 +120,8 @@ def self.choices4_ctype(site_id=nil)
80
120
  DcBigTable.choices4('dc_category_type', site_id)
81
121
  else
82
122
  opts = I18n.t('helpers.label.dc_category.choices4_ctype')
83
- # not defined
84
- return [] if opts.blank?
123
+ return [] if opts.blank? # not defined
124
+
85
125
  opts.split(',').inject([]) {|result, e| result << e.split(':')}
86
126
  end
87
127
  end
@@ -89,13 +129,11 @@ end
89
129
  #########################################################################
90
130
  # Returns choices for all categories, prepared for tree_select input field
91
131
  #########################################################################
92
- def self.choices4_categories(site_id=nil)
132
+ def self.choices4_categories(site_id = nil)
93
133
  qry = where(active: true)
94
- #
95
134
  ar = [nil]
96
135
  ar << site_id.id if site_id
97
136
  qry = qry.in(dc_site_id: ar)
98
- #
99
137
  qry.inject([]) { |result, category| result << [category.name, category.id, category.parent, category.order] }
100
138
  end
101
139
 
@@ -124,10 +124,11 @@ end
124
124
  # have site assigned will be selected. Too much designs to select often confuses
125
125
  # end user.
126
126
  ########################################################################
127
- def self.choices4_design(site=nil)
128
- list = site.nil? ? where(active: true) : where(active: true).in(site_id: [nil,site.id]).to_a
129
- list.sort! { |w1, w2| w1.description.casecmp(w2.description) }
130
- list.inject([]) { |r, design| r << [ design.description, design._id] }
127
+ def self.choices4_design(site)
128
+ (site.blank? ? where(active: true) : where(:site_id.in => [nil, BSON::ObjectId.from_string(site) ], active: true))
129
+ .only(:id, :description)
130
+ .order_by(description: 1)
131
+ .map { |design| [design.description, design.id] }
131
132
  end
132
133
 
133
134
  end
@@ -53,32 +53,33 @@ end
53
53
  ######################################################################
54
54
  def self.get_filter(filter)
55
55
  yaml = YAML.load(filter) rescue nil
56
- return yaml if yaml.nil?
57
- return nil if yaml['table'].nil? # old data
58
- #
56
+ return if yaml.nil? || yaml['table'].nil? # old data
57
+
59
58
  model = yaml['table'].classify.constantize
60
59
  field = yaml['field'] == 'id' ? '_id' : yaml['field'] # must be
61
- # evaluate
62
- if yaml['operation'] == 'eval' and model.respond_to?(yaml['field'])
63
- return model.send( yaml['field'] )
60
+ # evaluate
61
+ if yaml['operation'] == 'eval'
62
+ return eval(yaml['value']) if yaml['value'] && yaml['value'] != '#NIL' # evaluated as string
63
+ return model.send( yaml['field'] ) if model.respond_to?(yaml['field']) # defined as scope or method in the model
64
+ return
64
65
  end
65
- # if empty
66
+ # if empty
66
67
  if yaml['operation'] == 'empty'
67
- return model.in(field => [nil,''])
68
+ return model.in(field => [nil, ''])
68
69
  end
69
- # if value == NIL no filter is necessary
70
- return nil if yaml['value'].class == String and yaml['value'] == '#NIL'
70
+ # if value == NIL no filter is necessary
71
+ return if yaml['value'].class == String && yaml['value'] == '#NIL'
71
72
 
72
- # do regex if operation is like
73
+ # do regex if operation is like
73
74
  value = yaml['operation'] == 'like' ? /#{yaml['value']}/i : yaml['value']
74
- # when field type is ObjectId transform value
75
- if model.fields[field] and model.fields[field].type == BSON::ObjectId
75
+ # when field type is ObjectId transform value
76
+ if model.fields[field] && model.fields[field].type == BSON::ObjectId
76
77
  value = BSON::ObjectId.from_string(value) rescue nil
77
78
  end
78
- #
79
- if ['eq','like'].include?(yaml['operation'])
79
+
80
+ if %w[eq like].include?(yaml['operation'])
80
81
  model.where(field => value)
81
- # TODO in operator
82
+ # TODO in operator
82
83
  else
83
84
  model.where(field.to_sym.send(yaml['operation']) => value)
84
85
  end
@@ -109,7 +110,7 @@ end
109
110
  def self.get_filter_field(parent)
110
111
  return '' if parent.session[ parent.form['table'] ].nil?
111
112
 
112
- filter = parent.session[ parent.form['table'] ][:filter]
113
+ filter = parent.session[parent.form['table']][:filter]
113
114
  return '' if filter.nil?
114
115
 
115
116
  filter = YAML.load(filter) rescue nil
@@ -124,7 +125,7 @@ def self.get_filter_field(parent)
124
125
  # If field has choices available in labels, use them. This is most likely select input field.
125
126
  if field['name']
126
127
  choices = parent.t('helpers.label.' + parent.form['table'] + '.choices4_' + field['name'] )
127
- unless choices.match( 'translation missing' ) or choices.match('helpers.label')
128
+ unless choices.match(/translation missing/i) || choices.match('helpers.label')
128
129
  field['choices'] = choices
129
130
  end
130
131
  end
@@ -0,0 +1,237 @@
1
+ #--
2
+ # Copyright (c) 2022+ 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
+ # == Schema information
26
+ #
27
+ # Collection name: dc_images : Images
28
+ #
29
+ # _id BSON::ObjectId _id
30
+ # created_at Time created_at
31
+ # updated_at Time updated_at
32
+ # dc_site_id BSON::ObjectId Site id
33
+ # dc_user_id BSON::ObjectId User's id
34
+ # name String ip
35
+ # short String short name
36
+ # text String text
37
+ # size_l String Large image size
38
+ # size_m String Medium image size
39
+ # size_s String Small image size
40
+ #
41
+ # DRG CMS module for saveing and manipulating images.
42
+ #
43
+ # If you want to use this module you must install image magick tools
44
+ # and mini_magick ruby gem.
45
+ ##########################################################################
46
+ class DcImage
47
+ include Mongoid::Document
48
+ include Mongoid::Timestamps
49
+
50
+ field :name, type: String
51
+ field :img_type, type: String
52
+ field :text, type: String
53
+ field :short, type: String
54
+ field :keep_original, type: Boolean, default: false
55
+ field :size_o, type: String
56
+ field :size_l, type: String
57
+ field :size_m, type: String
58
+ field :size_s, type: String
59
+ field :categories, type: Array, default: []
60
+ field :created_by, type: BSON::ObjectId
61
+
62
+ belongs_to :dc_user
63
+
64
+ index dc_site_id: 1
65
+ index created_by: 1
66
+ index categories: 1
67
+
68
+ before_validation :set_original
69
+
70
+ validate :validate_image_values
71
+
72
+ #########################################################################
73
+ # checks that image size values are in correct format. Must be hsize[x]vsize (ex. 300x200)
74
+ #########################################################################
75
+ def set_original
76
+ if keep_original
77
+ if size_o.blank?
78
+ image = MiniMagick::Image.open(name)
79
+ self.size_o = "#{image.width}x#{image.height}"
80
+ end
81
+ else
82
+ self.size_o = ''
83
+ end
84
+ end
85
+
86
+ #########################################################################
87
+ # checks that image size values are in correct format. Must be hsize[x]vsize (ex. 300x200)
88
+ #########################################################################
89
+ def validate_image_values
90
+ %w[l m s o].each do |size|
91
+ field = "size_#{size}"
92
+ value = send(field)
93
+ next if value.blank?
94
+
95
+ a = value.strip.split(/x|\+/)
96
+ a[0, 2].each { |e| errors.add(field, I18n.t('drgcms.not_valid')) unless e.to_i > 0 }
97
+ end
98
+ end
99
+
100
+ #########################################################################
101
+ # For mapping categories array to input text_area field
102
+ #########################################################################
103
+ def cats_input=(what)
104
+ self.categories = if what.blank?
105
+ []
106
+ else
107
+ what.chomp.split("\n").map(&:downcase).map(&:strip)
108
+ end
109
+ end
110
+
111
+ #########################################################################
112
+ # For mapping categories array to input text_area field
113
+ #########################################################################
114
+ def cats_input
115
+ self.categories.join("\n")
116
+ end
117
+
118
+ #########################################################################
119
+ # For mapping categories array to display field
120
+ #########################################################################
121
+ def categories_line
122
+ categories ? categories.join(", ") : ''
123
+ end
124
+
125
+ #########################################################################
126
+ # Will return first available image starting from small up
127
+ #########################################################################
128
+ def first_available_image
129
+ image = %w[o s m l].each do |size|
130
+ field = "size_#{size}"
131
+ value = send(field)
132
+ return "#{id}-#{size}.#{img_type}" if value.present?
133
+ end
134
+ end
135
+
136
+ #########################################################################
137
+ # Will return size for large image
138
+ #########################################################################
139
+ def size_ls
140
+ size_l.blank? ? '' : size_l.split(/x|\+/)[0, 2].join('x')
141
+ end
142
+
143
+ #########################################################################
144
+ # Will set new size for large image
145
+ #########################################################################
146
+ def size_ls=(value)
147
+ self.size_l = value.blank? ? '' : value
148
+ end
149
+
150
+ #########################################################################
151
+ # Will return x offset for cropping large image
152
+ #########################################################################
153
+ def offset_lx
154
+ size_l.blank? ? '' : size_l.split(/x|\+/)[2].to_i
155
+ end
156
+
157
+ #########################################################################
158
+ # Will set x offset for cropping large image
159
+ #########################################################################
160
+ def offset_lx=(value)
161
+ self.size_l << (size_l.blank? ? '' : "+#{value}")
162
+ end
163
+
164
+ #########################################################################
165
+ # Will return y offset for cropping large image
166
+ #########################################################################
167
+ def offset_ly
168
+ size_l.blank? ? '' : size_l.split(/x|\+/)[3].to_i
169
+ end
170
+
171
+ #########################################################################
172
+ # Will set y offset for cropping large image
173
+ #########################################################################
174
+ def offset_ly=(value)
175
+ self.size_l << (size_l.blank? ? '' : "+#{value}")
176
+ end
177
+
178
+ def size_ms
179
+ size_m.blank? ? '' : size_m.split(/x|\+/)[0, 2].join('x')
180
+ end
181
+
182
+ def size_ms=(value)
183
+ self.size_m = value.blank? ? '' : value
184
+ end
185
+
186
+ def offset_mx
187
+ size_m.blank? ? '' : size_m.split(/x|\+/)[2].to_i
188
+ end
189
+
190
+ def offset_mx=(value)
191
+ self.size_m << (size_m.blank? ? '' : "+#{value}")
192
+ end
193
+
194
+ def offset_my
195
+ size_m.blank? ? '' : size_m.split(/x|\+/)[3].to_i
196
+ end
197
+
198
+ def offset_my=(value)
199
+ self.size_m << (size_m.blank? ? '' : "+#{value}")
200
+ end
201
+
202
+ def size_ss
203
+ size_s.blank? ? '' : size_s.split(/x|\+/)[0, 2].join('x')
204
+ end
205
+
206
+ def size_ss=(value)
207
+ self.size_s = value.blank? ? '' : value
208
+ end
209
+
210
+ def offset_sx
211
+ size_s.blank? ? '' : size_s.split(/x|\+/)[2].to_i
212
+ end
213
+
214
+ def offset_sx=(value)
215
+ self.size_s << (size_s.blank? ? '' : "+#{value}")
216
+ end
217
+
218
+ def offset_sy
219
+ size_s.blank? ? '' : size_s.split(/x|\+/)[3].to_i
220
+ end
221
+
222
+ def offset_sy=(value)
223
+ self.size_s << (size_s.blank? ? '' : "+#{value}")
224
+ end
225
+
226
+ #########################################################################
227
+ # Return all users that have contributed images
228
+ #########################################################################
229
+ def self.all_users
230
+ DcUser.where(:id.in => distinct(:created_by)).order_by(name: 1).map { |doc| [doc.name, doc.id] }
231
+ end
232
+
233
+ def self.html_code
234
+ 'code'
235
+ end
236
+
237
+ end
@@ -28,11 +28,10 @@
28
28
  ##########################################################################
29
29
  module DcInternals
30
30
  INTERNALS = {
31
- 'current_user' => 'session[:user_id]',
31
+ 'current_user' => 'session[:user_id].to_s',
32
32
  'current_user_name' => 'session[:user_name]',
33
- 'current_site' => 'dc_get_site.id'
33
+ 'current_site' => 'dc_get_site.id.to_s'
34
34
  }
35
- #
36
35
  @additions = {}
37
36
 
38
37
  ##########################################################################
@@ -40,7 +39,7 @@ module DcInternals
40
39
  # to be added to structure and be used together with predefined values.
41
40
  ##########################################################################
42
41
  def self.add_internal(hash)
43
- hash.each {|key,value| additions[key] = value}
42
+ hash.each { |key, value| additions[key] = value }
44
43
  end
45
44
 
46
45
  ##########################################################################
@@ -48,11 +47,8 @@ end
48
47
  # to be added to structure and be used together with predefined values.
49
48
  ##########################################################################
50
49
  def self.get(key)
51
- key = key.sub('@','')
52
-
53
- value = INTERNALS[key]
54
- value = @additions[key] if value.nil?
55
- value
50
+ key.sub!('@', '')
51
+ INTERNALS[key] || @additions[key]
56
52
  end
57
53
 
58
54
  end