drg_cms 0.6.1.11 → 0.7.0.8
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 +4 -4
- data/CHANGELOG.md +260 -0
- data/MIT-LICENSE +1 -1
- data/README.md +9 -5
- data/app/assets/javascripts/drg_cms/drg_cms.js +95 -34
- data/app/assets/javascripts/drg_cms/jquery.bpopup.js +372 -0
- data/app/assets/javascripts/drg_cms_application.js +1 -3
- data/app/assets/javascripts/drg_cms_cms.js +3 -4
- data/app/assets/stylesheets/drg_cms/drg_cms.css +37 -5
- data/app/assets/stylesheets/drg_cms/jstree.css +32 -27
- data/app/assets/stylesheets/drg_cms/select-multiple.css +6 -4
- data/app/controllers/cmsedit_controller.rb +22 -24
- data/app/controllers/dc_application_controller.rb +10 -9
- data/app/controllers/dc_common_controller.rb +14 -11
- data/app/controllers/dc_main_controller.rb +0 -1
- data/app/controls/dc_gallery_control.rb +46 -0
- data/app/controls/dc_image_control.rb +180 -0
- data/app/controls/dc_page_control.rb +3 -3
- data/app/controls/dc_poll_result_control.rb +7 -8
- data/app/controls/dc_report.rb +9 -4
- data/app/controls/design_element_settings_control.rb +88 -37
- data/app/forms/all_options.yml +18 -7
- data/app/forms/cms_menu.yml +10 -4
- data/app/forms/dc_category.yml +17 -8
- data/app/forms/dc_category_as_tree.yml +31 -0
- data/app/forms/dc_gallery.yml +1 -1
- data/app/forms/dc_image.yml +122 -0
- data/app/forms/dc_image_search.yml +72 -0
- data/app/forms/dc_page.yml +11 -8
- data/app/forms/dc_steps_template.yml +2 -1
- data/app/forms/help/dc_category_as_tree.en +4 -0
- data/app/forms/help/dc_category_as_tree.sl +5 -0
- data/app/helpers/cms_common_helper.rb +24 -16
- data/app/helpers/cms_edit_helper.rb +28 -35
- data/app/helpers/cms_helper.rb +21 -5
- data/app/helpers/cms_index_helper.rb +53 -38
- data/app/helpers/dc_application_helper.rb +95 -121
- data/app/helpers/dc_category_helper.rb +129 -0
- data/app/helpers/dc_image_helper.rb +127 -0
- data/app/models/concerns/dc_policy_rule_concern.rb +1 -1
- data/app/models/concerns/dc_user_concern.rb +12 -4
- data/app/models/dc_category.rb +62 -24
- data/app/models/dc_design.rb +5 -4
- data/app/models/dc_filter.rb +19 -18
- data/app/models/dc_image.rb +237 -0
- data/app/models/dc_internals.rb +5 -9
- data/app/models/dc_policy_role.rb +8 -8
- data/app/models/drgcms_form_fields/date_picker.rb +10 -12
- data/app/models/drgcms_form_fields/datetime_picker.rb +10 -11
- data/app/models/drgcms_form_fields/drgcms_field.rb +55 -30
- data/app/models/drgcms_form_fields/embedded.rb +11 -8
- data/app/models/drgcms_form_fields/journal_diff.rb +2 -2
- data/app/models/drgcms_form_fields/multitext_autocomplete.rb +51 -47
- data/app/models/drgcms_form_fields/select.rb +20 -14
- data/app/models/drgcms_form_fields/text_with_select.rb +5 -9
- data/app/models/drgcms_form_fields/tree_select.rb +20 -19
- data/app/renderers/dc_gallery_renderer.rb +10 -4
- data/app/renderers/dc_page_renderer.rb +7 -7
- data/app/renderers/dc_poll_renderer.rb +13 -12
- data/app/views/cmsedit/_edit_stuff.html.erb +1 -1
- data/app/views/cmsedit/edit.html.erb +1 -1
- data/app/views/cmsedit/index.html.erb +1 -1
- data/app/views/cmsedit/new.html.erb +1 -0
- data/app/views/layouts/content.html.erb +1 -1
- data/config/locales/drgcms_en.yml +16 -2
- data/config/locales/drgcms_sl.yml +15 -2
- data/config/locales/models_en.yml +33 -0
- data/config/locales/models_sl.yml +44 -1
- data/drg_cms.gemspec +3 -3
- data/lib/drg_cms/version.rb +1 -1
- data/lib/drg_cms.rb +19 -5
- data/lib/generators/convert_to_ar/USAGE +8 -0
- data/lib/generators/convert_to_ar/convert_to_ar_generator.rb +158 -0
- data/lib/tasks/dc_cleanup.rake +20 -42
- metadata +25 -14
- data/History.log +0 -109
- data/app/assets/javascripts/drg_cms/jquery.bpopup.min.js +0 -7
- 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
|
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
|
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 =
|
101
|
-
|
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
|
180
|
+
def additional_validates
|
173
181
|
if group && member.present?
|
174
182
|
errors.add('member', I18n.t('errors.messages.present'))
|
175
183
|
end
|
data/app/models/dc_category.rb
CHANGED
@@ -42,32 +42,72 @@
|
|
42
42
|
# is most useful for grouping news, blog entries ...
|
43
43
|
#####################################################################
|
44
44
|
class DcCategory
|
45
|
-
|
46
|
-
|
45
|
+
include Mongoid::Document
|
46
|
+
include Mongoid::Timestamps
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
|
data/app/models/dc_design.rb
CHANGED
@@ -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
|
128
|
-
|
129
|
-
|
130
|
-
|
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
|
data/app/models/dc_filter.rb
CHANGED
@@ -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
|
57
|
-
|
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'
|
63
|
-
return
|
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
|
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]
|
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 [
|
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[
|
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(
|
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
|
data/app/models/dc_internals.rb
CHANGED
@@ -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
|
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
|