drg_cms 0.7.0.2 → 0.7.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/drg_cms/drg_cms.js +110 -35
- data/app/assets/javascripts/drg_cms/jquery.bpopup.js +372 -0
- data/app/assets/javascripts/drg_cms_application.js +1 -1
- data/app/assets/javascripts/drg_cms_cms.js +1 -1
- data/app/assets/stylesheets/drg_cms/drg_cms.css +126 -36
- data/app/assets/stylesheets/drg_cms/select-multiple.css +6 -7
- data/app/controllers/cmsedit_controller.rb +78 -47
- data/app/controllers/dc_application_controller.rb +22 -25
- data/app/controllers/dc_common_controller.rb +9 -6
- data/app/controllers/dc_main_controller.rb +0 -1
- data/app/controls/{dc_category_control.rb → dc_gallery_control.rb} +15 -30
- 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 +38 -39
- data/app/controls/dc_report.rb +9 -4
- data/app/controls/dc_setup_control.rb +53 -0
- data/app/controls/design_element_settings_control.rb +88 -37
- data/app/forms/all_options.yml +20 -9
- data/app/forms/cms_menu.yml +14 -2
- 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_poll.yml +2 -1
- data/app/forms/dc_poll_result.yml +10 -7
- data/app/forms/dc_setup.yml +45 -0
- data/app/forms/dc_steps_template.yml +6 -2
- data/app/helpers/cms_common_helper.rb +36 -24
- data/app/helpers/cms_edit_helper.rb +26 -33
- data/app/helpers/cms_helper.rb +29 -12
- data/app/helpers/cms_index_helper.rb +109 -80
- data/app/helpers/dc_application_helper.rb +108 -86
- 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 +13 -5
- data/app/models/dc_big_table.rb +1 -1
- data/app/models/dc_category.rb +12 -0
- data/app/models/dc_design.rb +5 -4
- data/app/models/dc_filter.rb +24 -27
- data/app/models/dc_image.rb +237 -0
- data/app/models/dc_internals.rb +5 -9
- data/app/models/dc_memory.rb +2 -2
- data/app/models/dc_policy_role.rb +8 -8
- data/app/models/dc_setup.rb +111 -0
- data/app/models/drgcms_form_fields/datetime_picker.rb +1 -1
- data/app/models/drgcms_form_fields/drgcms_field.rb +9 -26
- data/app/models/drgcms_form_fields/embedded.rb +28 -17
- data/app/models/drgcms_form_fields/journal_diff.rb +2 -2
- data/app/models/drgcms_form_fields/multitext_autocomplete.rb +88 -76
- data/app/models/drgcms_form_fields/select.rb +41 -19
- data/app/models/drgcms_form_fields/text_with_select.rb +5 -9
- data/app/renderers/dc_big_menu_renderer.rb +18 -20
- data/app/renderers/dc_gallery_renderer.rb +10 -4
- data/app/renderers/dc_menu_renderer.rb +21 -58
- data/app/renderers/dc_page_renderer.rb +7 -7
- data/app/renderers/dc_poll_renderer.rb +13 -12
- data/app/renderers/dc_simple_menu_renderer.rb +1 -1
- data/app/views/cmsedit/_edit_stuff.html.erb +4 -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/config/locales/drgcms_en.yml +22 -2
- data/config/locales/drgcms_sl.yml +25 -6
- data/config/locales/models_en.yml +50 -1
- data/config/locales/models_sl.yml +60 -1
- data/drg_cms.gemspec +1 -1
- data/lib/drg_cms/version.rb +1 -1
- data/lib/drg_cms.rb +40 -27
- data/lib/generators/convert_to_ar/USAGE +8 -0
- data/lib/generators/convert_to_ar/convert_to_ar_generator.rb +158 -0
- data/lib/generators/new_drg_form/new_drg_form_generator.rb +32 -14
- metadata +19 -10
- data/app/assets/javascripts/drg_cms/jquery.bpopup.min.js +0 -7
- data/app/views/layouts/__cmsedit.html.erb +0 -16
@@ -260,7 +260,7 @@ def dc_table_title(text, result_set = nil)
|
|
260
260
|
c = %(<div class="dc-title">#{text})
|
261
261
|
c << dc_help_button(result_set)
|
262
262
|
|
263
|
-
if result_set
|
263
|
+
if result_set&.respond_to?(:current_page)
|
264
264
|
c << %(<div class="dc-paginate">#{paginate(result_set, :params => {action: 'index', clear: 'no', filter: nil})}</div>)
|
265
265
|
end
|
266
266
|
c << '<div style="clear: both;"></div></div>'
|
@@ -268,26 +268,27 @@ def dc_table_title(text, result_set = nil)
|
|
268
268
|
end
|
269
269
|
|
270
270
|
############################################################################
|
271
|
-
# Creates title for cmsedit edit action dialog.
|
272
|
-
#
|
271
|
+
# Creates title for cmsedit edit action dialog.
|
272
|
+
#
|
273
273
|
# Returns:
|
274
274
|
# String. HTML code for title.
|
275
275
|
############################################################################
|
276
276
|
def dc_edit_title
|
277
277
|
session[:form_processing] = "form:title:"
|
278
|
-
|
278
|
+
title_data = @form['form']['title']
|
279
|
+
if title_data.class == String
|
280
|
+
t(title_data, title_data)
|
279
281
|
# defined as form:title:edit
|
280
|
-
|
281
|
-
t(
|
282
|
-
elsif
|
283
|
-
t(
|
282
|
+
elsif title_data&.dig('edit') && !@form['readonly']
|
283
|
+
t( title_data['edit'], title_data['edit'] )
|
284
|
+
elsif title_data&.dig('show') && @form['readonly']
|
285
|
+
t( title_data['show'], title_data['show'] )
|
284
286
|
else
|
285
|
-
# concatenate title
|
286
287
|
c = (@form['readonly'] ? t('drgcms.show') : t('drgcms.edit')) + " : "
|
287
288
|
c << (@form['title'].class == String ? t( @form['title'], @form['title'] ) : t_tablename(@form['table']))
|
288
|
-
|
289
|
-
|
290
|
-
c << "#{@record[
|
289
|
+
# add description field value to title
|
290
|
+
field_name = title_data['field'] if title_data
|
291
|
+
c << " : #{@record[ field_name ]}" if field_name && @record.respond_to?(field_name)
|
291
292
|
c
|
292
293
|
end
|
293
294
|
end
|
@@ -300,14 +301,18 @@ end
|
|
300
301
|
############################################################################
|
301
302
|
def dc_new_title
|
302
303
|
session[:form_processing] = "form:title:"
|
303
|
-
|
304
|
+
title_data = @form['form']['title']
|
305
|
+
if title_data.class == String
|
306
|
+
t(title_data, title_data)
|
304
307
|
# defined as form:title:new
|
305
|
-
|
306
|
-
t(
|
308
|
+
elsif title_data&.dig('new')
|
309
|
+
t( title_data['new'], title_data['new'] )
|
307
310
|
else
|
308
311
|
# in memory structures
|
309
312
|
if @form['table'] == 'dc_memory'
|
310
|
-
t( @form['title'], @form['title'] )
|
313
|
+
return t( @form['title'], @form['title'] ) if @form['title']
|
314
|
+
|
315
|
+
t("#{@form['i18n_prefix']}.tabletitle", '')
|
311
316
|
else
|
312
317
|
"#{t('drgcms.new')} : #{t_tablename(@form['table'])}"
|
313
318
|
end
|
@@ -684,51 +689,40 @@ end
|
|
684
689
|
############################################################################
|
685
690
|
# Returns list of all collections (tables) as array of choices for usage in select fields.
|
686
691
|
# List is collected from cms_menu.yml files and may not include all collections used in application.
|
687
|
-
# Currently list is only used for helping defining collection names on dc_permission form.
|
688
|
-
#
|
692
|
+
# Currently list is only used for helping defining collection names on dc_permission form.
|
693
|
+
#
|
689
694
|
# Example (as used in forms):
|
690
695
|
# form:
|
691
696
|
# fields:
|
692
697
|
# 10:
|
693
698
|
# name: table_name
|
694
699
|
# type: text_with_select
|
695
|
-
# eval: dc_choices4_all_collections
|
700
|
+
# eval: dc_choices4_all_collections
|
696
701
|
############################################################################
|
697
702
|
def dc_choices4_all_collections
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
menu = YAML.load_file(filename) rescue nil # load menu
|
704
|
-
next if menu.nil? or !menu['menu'] # not menu or error
|
705
|
-
menu['menu'].each do |section|
|
706
|
-
next unless section.last['items'] # next if no items
|
707
|
-
section.last['items'].each do |k, v| # look for caption and
|
708
|
-
key = v['table']
|
709
|
-
choices[key] ||= "#{key} - #{t(v['caption'], v['caption'])}"
|
710
|
-
end
|
711
|
-
end
|
712
|
-
end
|
713
|
-
choices.invert.to_a.sort # hash has to be inverted for values to be returned right
|
703
|
+
models = Mongoid.models.map(&:to_s).uniq.map(&:underscore).delete_if { |e| e.match('/') }
|
704
|
+
models.sort.inject([]) do |r, model_name|
|
705
|
+
r << ["#{model_name} - #{t("helpers.label.#{model_name}.tabletitle", '')}", model_name]
|
706
|
+
end
|
714
707
|
end
|
715
708
|
|
716
709
|
##########################################################################
|
717
|
-
#
|
710
|
+
# Code for top CMS menu.
|
718
711
|
##########################################################################
|
719
|
-
def
|
712
|
+
def dc_cms_menu
|
720
713
|
menus = {}
|
721
714
|
DrgCms.paths(:forms).reverse.each do |path|
|
722
715
|
filename = "#{path}/cms_menu.yml"
|
723
|
-
next
|
724
|
-
|
725
|
-
|
726
|
-
menus = CmsHelper.forms_merge(menu['menu'], menus)
|
727
|
-
|
716
|
+
next if !File.exist?(filename)
|
717
|
+
|
718
|
+
menu = YAML.load_file(filename) rescue nil # load menu
|
719
|
+
menus = CmsHelper.forms_merge(menu['menu'], menus) if menu.dig('menu') # merge menus
|
720
|
+
end
|
728
721
|
|
729
722
|
html = '<ul>'
|
730
723
|
menus.to_a.sort.each do |index, menu| # sort menus, result is array of sorted hashes
|
731
724
|
next unless menu['caption']
|
725
|
+
|
732
726
|
icon = menu['icon'].match('/') ? image_tag(menu['icon']) : fa_icon(menu['icon']) #external or fa- image
|
733
727
|
html << %(<li class="cmsedit-top-level-menu"><div>#{icon}#{t(menu['caption'])}</div><ul>)
|
734
728
|
menu['items'].to_a.sort.each do |index1, value| # again, sort menu items first
|
@@ -736,19 +730,18 @@ def dc_choices4_cmsmenu
|
|
736
730
|
opts = { target: value['target'] || 'iframe_cms' }
|
737
731
|
"<li>#{dc_link_to(t(value['caption']), value['icon'] || '', value['link'], opts)}</li>"
|
738
732
|
else
|
739
|
-
opts =
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
}
|
733
|
+
opts = { controller: value['controller'], action: value['action'],
|
734
|
+
table: value['table'], form_name: value['form_name'] || value['table'],
|
735
|
+
target: value['target'] || 'iframe_cms',
|
736
|
+
}
|
737
|
+
# additional parameters
|
738
|
+
value['params'].each { |k, v| opts[k] = dc_value_for_parameter(v) } if value['params']
|
746
739
|
"<li>#{dc_link_to(t(value['caption']), value['icon'] || '', opts)}</li>"
|
747
740
|
end
|
748
741
|
end
|
749
742
|
html << '</ul></li>'
|
750
743
|
end
|
751
|
-
html
|
744
|
+
html.html_safe
|
752
745
|
end
|
753
746
|
|
754
747
|
############################################################################
|
@@ -760,7 +753,7 @@ def dc_choices4_folders_list
|
|
760
753
|
home = File.join(public,dc_get_site.files_directory)
|
761
754
|
choices = Dir.glob(home + '/**/*/').select { |fn| File.directory?(fn) }
|
762
755
|
choices << home # add home
|
763
|
-
choices.collect! {|e| e.gsub(public,'')} # remove public part
|
756
|
+
choices.collect! { |e| e.gsub(public,'') } # remove public part
|
764
757
|
choices.sort
|
765
758
|
end
|
766
759
|
|
@@ -782,7 +775,7 @@ end
|
|
782
775
|
# type: select
|
783
776
|
# eval: dc_choices4('dc_poll','name','_id')
|
784
777
|
############################################################################
|
785
|
-
def dc_choices4(model, name, id='_id', options = {})
|
778
|
+
def dc_choices4(model, name, id = '_id', options = {})
|
786
779
|
model = model.classify.constantize
|
787
780
|
qry = model.only(id, name)
|
788
781
|
if (param = options[:site])
|
@@ -792,8 +785,6 @@ def dc_choices4(model, name, id='_id', options = {})
|
|
792
785
|
end
|
793
786
|
qry = qry.and(active: true) if model.method_defined?(:active)
|
794
787
|
qry = qry.order_by(name => 1).collation(locale: I18n.locale.to_s)
|
795
|
-
#choices = qry.inject([]) {|result,e| result << [ e[name], e[id] ]}
|
796
|
-
#choices.sort_alphabetical_by(&:first) # use UTF-8 sort
|
797
788
|
qry.map { |e| [e[name], e[id]] }
|
798
789
|
end
|
799
790
|
|
@@ -864,10 +855,10 @@ def dc_user_can_view(ctrl, policy_id)
|
|
864
855
|
policies = if site.inherit_policy.blank?
|
865
856
|
site.dc_policies
|
866
857
|
else
|
867
|
-
|
858
|
+
Mongo::QueryCache.cache { DcSite.find(site.inherit_policy) }.dc_policies
|
868
859
|
end
|
869
860
|
# permission defined by default policy
|
870
|
-
default_policy =
|
861
|
+
default_policy = Mongo::QueryCache.cache { policies.find_by(is_default: true) }
|
871
862
|
return cache_add(policy_id, false, 'Default access policy not found for the site!') unless default_policy
|
872
863
|
|
873
864
|
permissions = {}
|
@@ -875,14 +866,14 @@ def dc_user_can_view(ctrl, policy_id)
|
|
875
866
|
# update permissions with defined policy
|
876
867
|
part_policy = nil
|
877
868
|
if policy_id
|
878
|
-
part_policy =
|
869
|
+
part_policy = Mongo::QueryCache.cache { policies.find(policy_id) }
|
879
870
|
return cache_add(policy_id, false, 'Access policy not found for part!') unless part_policy
|
880
871
|
|
881
872
|
part_policy.dc_policy_rules.to_a.each { |v| permissions[v.dc_policy_role_id] = v.permission }
|
882
873
|
end
|
883
874
|
# apply guest role if no roles defined
|
884
875
|
if ctrl.session[:user_roles].nil?
|
885
|
-
role =
|
876
|
+
role = Mongo::QueryCache.cache { DcPolicyRole.find_by(system_name: 'guest', active: true) }
|
886
877
|
return cache_add(policy_id, false, 'System guest role not defined!') unless role
|
887
878
|
|
888
879
|
ctrl.session[:user_roles] = [role.id]
|
@@ -1008,7 +999,15 @@ def dc_big_table(key)
|
|
1008
999
|
desc = v.value if desc.blank? # still blank. Use value as description
|
1009
1000
|
ret << [desc, v.value]
|
1010
1001
|
end
|
1011
|
-
ret
|
1002
|
+
ret.sort_alphabetical_by(&:first)
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
########################################################################
|
1006
|
+
# Will return name for value defined in dc_big_table
|
1007
|
+
########################################################################
|
1008
|
+
def dc_big_table_name_for_value(key, value)
|
1009
|
+
dc_big_table(key).each { |k, val| return k if val.to_s == value.to_s}
|
1010
|
+
'???'
|
1012
1011
|
end
|
1013
1012
|
|
1014
1013
|
########################################################################
|
@@ -1073,25 +1072,25 @@ end
|
|
1073
1072
|
########################################################################
|
1074
1073
|
def dc_internal_var(object, var_name, current_document = nil)
|
1075
1074
|
begin
|
1076
|
-
case
|
1077
|
-
when
|
1078
|
-
when
|
1079
|
-
when
|
1080
|
-
when
|
1081
|
-
when
|
1075
|
+
case object
|
1076
|
+
when 'session' then _origin.session[var_name]
|
1077
|
+
when 'params' then _origin.params[var_name]
|
1078
|
+
when 'site' then _origin.dc_get_site.send(var_name)
|
1079
|
+
when 'page' then _origin.page.send(var_name)
|
1080
|
+
when 'record' then
|
1082
1081
|
current_document ? current_document.send(var_name) : _origin.record.send(var_name)
|
1083
|
-
when
|
1082
|
+
when 'class' then
|
1084
1083
|
clas, method_name = var_name.split('.')
|
1085
1084
|
klas = clas.classify.constantize
|
1086
1085
|
# call method. Error will be caught below.
|
1087
1086
|
klas.send(method_name)
|
1088
1087
|
else
|
1089
|
-
'
|
1088
|
+
'dc_internal: UNKNOWN OBJECT'
|
1090
1089
|
end
|
1091
1090
|
rescue Exception => e
|
1092
1091
|
Rails.logger.debug "\ndc_internal_var. Runtime error. #{e.message}\n"
|
1093
1092
|
Rails.logger.debug(e.backtrace.join($/)) if Rails.env.development?
|
1094
|
-
'
|
1093
|
+
'dc_internal: ERROR'
|
1095
1094
|
end
|
1096
1095
|
end
|
1097
1096
|
|
@@ -1119,14 +1118,13 @@ end
|
|
1119
1118
|
# Returns:
|
1120
1119
|
# HTML data to be embedded into page header
|
1121
1120
|
#######################################################################
|
1122
|
-
def dc_get_json_ld
|
1123
|
-
return '' if @json_ld.
|
1121
|
+
def dc_get_json_ld
|
1122
|
+
return '' if @json_ld.blank?
|
1124
1123
|
|
1125
|
-
%
|
1124
|
+
%(
|
1126
1125
|
<script type="application/ld+json">
|
1127
|
-
#{JSON.pretty_generate({'@context' => 'http://schema.org', '@graph' => @json_ld})}
|
1128
|
-
</script>
|
1129
|
-
].html_safe
|
1126
|
+
#{JSON.pretty_generate({ '@context' => 'http://schema.org', '@graph' => @json_ld })}
|
1127
|
+
</script>).html_safe
|
1130
1128
|
end
|
1131
1129
|
|
1132
1130
|
########################################################################
|
@@ -1145,21 +1143,40 @@ def dc_add_json_ld(element)
|
|
1145
1143
|
end
|
1146
1144
|
|
1147
1145
|
########################################################################
|
1148
|
-
# Will return meta data for SEO optimizations
|
1146
|
+
# Will return meta data for SEO optimizations.
|
1147
|
+
# It will also create special link rel="canonical" tag if defined in meta tags or page document.
|
1149
1148
|
#
|
1150
1149
|
# Returns:
|
1151
1150
|
# HTML data to be embedded into page header
|
1152
1151
|
#######################################################################
|
1153
|
-
def dc_get_seo_meta_tags
|
1152
|
+
def dc_get_seo_meta_tags
|
1154
1153
|
html = ''
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1154
|
+
has_canonical = false
|
1155
|
+
html << @meta_tags.inject('') do |r, tag|
|
1156
|
+
r << if tag.first.match('canonical')
|
1157
|
+
has_canonical = true
|
1158
|
+
dc_get_link_canonical_tag(tag.last)
|
1159
|
+
else
|
1160
|
+
%(<meta #{tag.first} content="#{tag.last}">\n )
|
1161
|
+
end
|
1159
1162
|
end if @meta_tags
|
1163
|
+
html << dc_get_link_canonical_tag(@page&.canonical_link) unless has_canonical
|
1160
1164
|
html.html_safe
|
1161
1165
|
end
|
1162
1166
|
|
1167
|
+
########################################################################
|
1168
|
+
# helper for setting canonical link on the page
|
1169
|
+
#######################################################################
|
1170
|
+
def dc_get_link_canonical_tag(href = nil)
|
1171
|
+
return %(<link rel="canonical" href="#{request.url}">\n) if href.blank?
|
1172
|
+
|
1173
|
+
unless href.match(/^http/i)
|
1174
|
+
uri = URI.parse(request.url)
|
1175
|
+
href = "#{uri.scheme}://#{uri.host}/#{href.delete_prefix('/')}"
|
1176
|
+
end
|
1177
|
+
%(<link rel="canonical" href="#{href}">\n)
|
1178
|
+
end
|
1179
|
+
|
1163
1180
|
########################################################################
|
1164
1181
|
# Will add a meta tag to internal hash structure. If meta tag already exists it
|
1165
1182
|
# will be overwritten.
|
@@ -1170,6 +1187,7 @@ end
|
|
1170
1187
|
########################################################################
|
1171
1188
|
def dc_add_meta_tag(type, name, content)
|
1172
1189
|
return if content.blank?
|
1190
|
+
|
1173
1191
|
@meta_tags ||= {}
|
1174
1192
|
key = "#{type}=\"#{name}\""
|
1175
1193
|
@meta_tags[key] = content
|
@@ -1187,8 +1205,8 @@ end
|
|
1187
1205
|
# Returns:
|
1188
1206
|
# [String] alt="image-tag"
|
1189
1207
|
#######################################################################
|
1190
|
-
def dc_img_alt_tag(file_name, text=nil)
|
1191
|
-
|
1208
|
+
def dc_img_alt_tag(file_name, text = nil)
|
1209
|
+
%( alt="#{dc_img_alt(file_name, text)}" ).html_safe
|
1192
1210
|
end
|
1193
1211
|
|
1194
1212
|
#######################################################################
|
@@ -1203,15 +1221,19 @@ end
|
|
1203
1221
|
# Returns:
|
1204
1222
|
# [String] alt_image_name
|
1205
1223
|
#######################################################################
|
1206
|
-
def dc_img_alt(file_name, text=nil)
|
1207
|
-
return text
|
1224
|
+
def dc_img_alt(file_name, text = nil)
|
1225
|
+
return text if text.present?
|
1226
|
+
|
1208
1227
|
name = File.basename(file_name.to_s)
|
1209
|
-
name[0,name.index('.')].downcase rescue name
|
1228
|
+
name[0, name.index('.')].downcase rescue name
|
1210
1229
|
end
|
1211
1230
|
|
1212
1231
|
private
|
1213
1232
|
|
1214
|
-
|
1233
|
+
########################################################################
|
1234
|
+
# To cache localy dc_user_can_view response for a single call. It has large gains on sites
|
1235
|
+
# with large menus.
|
1236
|
+
########################################################################
|
1215
1237
|
def cache_add(id, can_view, msg)
|
1216
1238
|
@can_view_cache[id] = [can_view, msg]
|
1217
1239
|
end
|
@@ -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 first_dc_image(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 select_links_for_dc_image(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
|
##########################################################################
|
@@ -141,7 +149,7 @@ end
|
|
141
149
|
# Will return list of available groups
|
142
150
|
##########################################################################
|
143
151
|
def self.groups_for_select
|
144
|
-
where(group: true, active: true).order_by(name: 1).
|
152
|
+
where(group: true, active: true).order_by(name: 1).map { [_1.name, _1.id] }
|
145
153
|
end
|
146
154
|
|
147
155
|
private
|
@@ -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_big_table.rb
CHANGED
data/app/models/dc_category.rb
CHANGED
@@ -63,6 +63,16 @@ validates :name, presence: true
|
|
63
63
|
|
64
64
|
before_destroy :can_destroy?
|
65
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
|
+
|
66
76
|
private
|
67
77
|
|
68
78
|
#########################################################################
|
@@ -88,6 +98,8 @@ def self.values_for_parent(site_id = nil) #:nodoc:
|
|
88
98
|
parent = v.parent
|
89
99
|
until parent.nil?
|
90
100
|
doc = find(parent)
|
101
|
+
break if doc.nil?
|
102
|
+
|
91
103
|
name = doc.name + ' / ' + name
|
92
104
|
parent = doc.parent
|
93
105
|
end
|
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
|