drg_cms 0.6.0.1 → 0.6.1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/drg_cms/drg_cms.js +454 -145
  3. data/app/assets/javascripts/drg_cms_application.js +1 -1
  4. data/app/assets/stylesheets/drg_cms/drg_cms.css +635 -244
  5. data/app/assets/stylesheets/drg_cms/select-multiple.css +18 -12
  6. data/app/assets/stylesheets/drg_cms_cms.css +1 -1
  7. data/app/controllers/cmsedit_controller.rb +515 -335
  8. data/app/controllers/dc_application_controller.rb +378 -111
  9. data/app/controllers/dc_common_controller.rb +105 -14
  10. data/app/{controllers → controls}/browse_models_control.rb +0 -0
  11. data/app/controls/dc_help_control.rb +126 -0
  12. data/app/{controllers → controls}/dc_page_control.rb +24 -8
  13. data/app/controls/dc_poll_result_control.rb +88 -0
  14. data/app/controls/dc_report.rb +223 -0
  15. data/app/{controllers → controls}/design_element_settings_control.rb +0 -0
  16. data/app/forms/all_options.yml +44 -9
  17. data/app/forms/cms_menu.yml +28 -18
  18. data/app/forms/dc_ad.yml +11 -22
  19. data/app/forms/dc_big_table.yml +1 -0
  20. data/app/forms/dc_big_table_value.yml +1 -0
  21. data/app/forms/dc_category.yml +2 -1
  22. data/app/forms/dc_design.yml +20 -16
  23. data/app/forms/dc_filter.yml +3 -6
  24. data/app/forms/dc_help_1.yml +109 -0
  25. data/app/forms/dc_journal.yml +3 -1
  26. data/app/forms/dc_json_ld.yml +59 -0
  27. data/app/forms/dc_key_value.yml +32 -0
  28. data/app/forms/dc_link.yml +1 -1
  29. data/app/forms/dc_menu.yml +2 -0
  30. data/app/forms/dc_menu_item.yml +2 -0
  31. data/app/forms/dc_page.yml +3 -5
  32. data/app/forms/dc_part.yml +1 -0
  33. data/app/forms/dc_piece.yml +1 -0
  34. data/app/forms/dc_poll.yml +15 -5
  35. data/app/forms/dc_poll_item.yml +2 -1
  36. data/app/forms/dc_poll_result.yml +83 -0
  37. data/app/forms/dc_poll_result_export.yml +35 -0
  38. data/app/forms/dc_seo.yml +33 -0
  39. data/app/forms/dc_simple_menu.yml +2 -0
  40. data/app/forms/dc_site.yml +4 -12
  41. data/app/forms/dc_user.yml +27 -11
  42. data/app/forms/dc_user_role.yml +3 -0
  43. data/app/forms/json_ld_schema.yml +168 -0
  44. data/app/helpers/cms_common_helper.rb +375 -0
  45. data/app/helpers/cms_edit_helper.rb +506 -0
  46. data/app/helpers/cms_helper.rb +268 -0
  47. data/app/helpers/cms_index_helper.rb +580 -0
  48. data/app/helpers/dc_application_helper.rb +218 -306
  49. data/app/models/concerns/dc_page_concern.rb +40 -6
  50. data/app/models/concerns/dc_policy_rule_concern.rb +20 -8
  51. data/app/models/concerns/dc_seo_concern.rb +66 -0
  52. data/app/models/concerns/dc_site_concern.rb +67 -44
  53. data/app/models/concerns/dc_user_concern.rb +57 -18
  54. data/app/models/dc_design.rb +30 -18
  55. data/app/models/dc_filter.rb +22 -13
  56. data/app/models/dc_json_ld.rb +152 -0
  57. data/app/models/dc_key_value.rb +48 -0
  58. data/app/models/dc_key_value_store.rb +1 -0
  59. data/app/models/dc_memory.rb +8 -1
  60. data/app/models/dc_page.rb +0 -1
  61. data/app/models/dc_permission.rb +49 -9
  62. data/app/models/dc_policy.rb +25 -14
  63. data/app/models/dc_policy_role.rb +22 -11
  64. data/app/models/dc_poll.rb +39 -19
  65. data/app/models/dc_poll_result.rb +46 -0
  66. data/app/models/dc_temp.rb +140 -0
  67. data/app/models/dc_user_role.rb +2 -2
  68. data/app/models/drgcms_form_fields.rb +12 -1
  69. data/app/models/drgcms_form_fields/action.rb +61 -0
  70. data/app/models/drgcms_form_fields/comment.rb +8 -4
  71. data/app/models/drgcms_form_fields/date_picker.rb +11 -9
  72. data/app/models/drgcms_form_fields/date_select.rb +1 -1
  73. data/app/models/drgcms_form_fields/datetime_picker.rb +12 -10
  74. data/app/models/drgcms_form_fields/datetime_select.rb +1 -1
  75. data/app/models/drgcms_form_fields/drgcms_field.rb +55 -9
  76. data/app/models/drgcms_form_fields/embedded.rb +26 -16
  77. data/app/models/drgcms_form_fields/file_field.rb +52 -0
  78. data/app/models/drgcms_form_fields/file_select.rb +2 -2
  79. data/app/models/drgcms_form_fields/hash_field.rb +90 -0
  80. data/app/models/drgcms_form_fields/hidden_field.rb +1 -1
  81. data/app/models/drgcms_form_fields/html_field.rb +1 -1
  82. data/app/models/drgcms_form_fields/link_to.rb +2 -2
  83. data/app/models/drgcms_form_fields/method.rb +66 -0
  84. data/app/models/drgcms_form_fields/multitext_autocomplete.rb +23 -14
  85. data/app/models/drgcms_form_fields/number_field.rb +15 -6
  86. data/app/models/drgcms_form_fields/radio.rb +96 -0
  87. data/app/models/drgcms_form_fields/readonly.rb +2 -2
  88. data/app/models/drgcms_form_fields/select.rb +92 -29
  89. data/app/models/drgcms_form_fields/text_area.rb +1 -1
  90. data/app/models/drgcms_form_fields/text_autocomplete.rb +31 -17
  91. data/app/models/drgcms_form_fields/text_field.rb +1 -1
  92. data/app/models/drgcms_form_fields/text_with_select.rb +6 -3
  93. data/app/models/drgcms_form_fields/tree_select.rb +15 -4
  94. data/app/{helpers → renderers}/dc_ad_renderer.rb +0 -0
  95. data/app/{helpers → renderers}/dc_big_menu_renderer.rb +1 -0
  96. data/app/{helpers → renderers}/dc_captcha_renderer.rb +0 -0
  97. data/app/{helpers → renderers}/dc_common_renderer.rb +0 -0
  98. data/app/{helpers → renderers}/dc_gallery_renderer.rb +1 -0
  99. data/app/{helpers → renderers}/dc_menu_renderer.rb +11 -4
  100. data/app/{helpers → renderers}/dc_page_renderer.rb +1 -0
  101. data/app/{helpers → renderers}/dc_part_renderer.rb +5 -4
  102. data/app/{helpers → renderers}/dc_piece_renderer.rb +1 -1
  103. data/app/{helpers → renderers}/dc_poll_renderer.rb +91 -64
  104. data/app/{helpers → renderers}/dc_renderer.rb +1 -0
  105. data/app/{helpers → renderers}/dc_simple_menu_renderer.rb +1 -0
  106. data/app/views/cmsedit/{remove_edit_stuff.js.erb → __remove_edit_stuff.js.erb} +0 -0
  107. data/app/views/cmsedit/{show.html.erb → __show.html.erb} +0 -0
  108. data/app/views/cmsedit/_edit_stuff.html.erb +4 -25
  109. data/app/views/cmsedit/_form.html.erb +4 -3
  110. data/app/views/cmsedit/_result.html.erb +2 -3
  111. data/app/views/cmsedit/edit.html.erb +4 -1
  112. data/app/views/cmsedit/index.html.erb +7 -1
  113. data/app/views/cmsedit/new.html.erb +3 -1
  114. data/app/views/dc_common/_help.html.erb +17 -0
  115. data/app/views/layouts/models.html.erb +2 -1
  116. data/config/locales/drgcms_en.yml +27 -3
  117. data/config/locales/drgcms_sl.yml +32 -5
  118. data/config/locales/models_en.yml +65 -17
  119. data/config/locales/models_sl.yml +69 -18
  120. data/drg_cms.gemspec +1 -1
  121. data/lib/drg_cms.rb +61 -1
  122. data/lib/drg_cms/version.rb +1 -1
  123. data/lib/generators/new_drg_form/new_drg_form_generator.rb +9 -2
  124. data/lib/tasks/database.rake +6 -56
  125. metadata +73 -54
  126. data/app/assets/stylesheets/drg_cms/__jquery-ui.css +0 -339
  127. data/app/helpers/application_helper.rb +0 -2
  128. data/app/helpers/cmsedit_helper.rb +0 -888
  129. data/app/models/dc_dummy.rb +0 -102
  130. data/test/fixtures/drg_cms_test_data.rb +0 -87
@@ -1,4 +1,3 @@
1
- #coding: utf-8
2
1
  #--
3
2
  # Copyright (c) 2012+ Damjan Rems
4
3
  #
@@ -33,7 +32,6 @@ include Mongoid::Document
33
32
  include Mongoid::Timestamps
34
33
 
35
34
  field :subject, type: String, default: ''
36
- field :title, type: String
37
35
  field :subject_link, type: String, default: ''
38
36
  field :alt_link, type: String, default: ''
39
37
  field :sub_subject, type: String, default: ''
@@ -56,16 +54,19 @@ field :active, type: Boolean, default: true
56
54
  field :created_by, type: BSON::ObjectId
57
55
  field :updated_by, type: BSON::ObjectId
58
56
  field :kats, type: Array # Categories
59
-
57
+ # IFRAME
60
58
  field :if_url, type: String
61
59
  field :if_border, type: Integer, default: 0
62
60
  field :if_width, type: Integer
63
61
  field :if_height, type: Integer
64
62
  field :if_scroll, type: String
65
63
  field :if_id, type: String
66
- field :if_class, type: String
64
+ field :if_class, type: String
67
65
  field :if_params, type: String
68
66
 
67
+ # SEO
68
+ include DcSeoConcern
69
+
69
70
  field :policy_id, type: BSON::ObjectId
70
71
 
71
72
  embeds_many :dc_parts
@@ -80,6 +81,17 @@ index alt_link: 1
80
81
  before_save :do_before_save
81
82
 
82
83
  validates :publish_date, presence: true
84
+ validate :validate_images_alt_present
85
+
86
+ after_save :cache_clear
87
+ after_destroy :cache_clear
88
+
89
+ ####################################################################
90
+ # Clear cache if cache is configured
91
+ ####################################################################
92
+ def cache_clear
93
+ DrgCms.cache_clear(:dc_page)
94
+ end
83
95
 
84
96
  ######################################################################
85
97
  # Will return subject_link. Field name link should be common for all documents
@@ -88,7 +100,15 @@ validates :publish_date, presence: true
88
100
  def link
89
101
  subject_link
90
102
  end
91
-
103
+
104
+ ######################################################################
105
+ # Will return validation error if all images in body field do not have
106
+ # alt attribute present.
107
+ ######################################################################
108
+ def validate_images_alt_present
109
+ errors.add('body', I18n.t('drgcms.img_alt_not_present')) unless DcPage.images_alt_present?(self.body)
110
+ end
111
+
92
112
  protected
93
113
 
94
114
  ######################################################################
@@ -109,7 +129,7 @@ end
109
129
  # than link size is not larger than 100 chars.
110
130
  ######################################################################
111
131
  def self.clear_link(link)
112
- link.gsub!(/\.|\?|\!\&|»|«|\,|\"|\'|\:/,'')
132
+ link.gsub!(/\.|\?|\!\&|\||»|«|\,|\"|\'|\:/,'')
113
133
  link.gsub!('<br>','')
114
134
  link.gsub!('–','-')
115
135
  link.gsub!(' ','-')
@@ -144,6 +164,20 @@ def self.dc_filters
144
164
  'field' => 'dc_site_id', 'value' => '@current_site'}
145
165
  end
146
166
 
167
+ ######################################################################
168
+ # Clears subject link of chars that shouldn't be there and also takes care
169
+ # than link size is not larger than 100 chars.
170
+ ######################################################################
171
+ def self.images_alt_present?(text)
172
+ return true if text.blank?
173
+ #
174
+ document = Nokogiri::HTML.parse(text)
175
+ document.xpath('//img').each do |image|
176
+ return false if !image.attributes['alt'] or image.attributes['alt'].text.blank?
177
+ end
178
+ true
179
+ end
180
+
147
181
  end
148
182
 
149
183
  end
@@ -25,17 +25,20 @@
25
25
  # ActiveSupport::Concern definition for DcPolicyRule class.
26
26
  #########################################################################
27
27
  module DcPolicyRuleConcern
28
- extend ActiveSupport::Concern
29
- included do
28
+ extend ActiveSupport::Concern
29
+ included do
30
30
 
31
- include Mongoid::Document
32
- include Mongoid::Timestamps
31
+ include Mongoid::Document
32
+ include Mongoid::Timestamps
33
33
 
34
- belongs_to :dc_policy_role
34
+ belongs_to :dc_policy_role
35
35
 
36
- field :permission, type: Integer, default: 0
36
+ field :permission, type: Integer, default: 0
37
37
 
38
- embedded_in :policy_rules, polymorphic: true
38
+ embedded_in :policy_rules, polymorphic: true
39
+
40
+ after_save :cache_clear
41
+ after_destroy :cache_clear
39
42
 
40
43
  #########################################################################
41
44
  # Returns values for permissions ready to be used in select field.
@@ -50,7 +53,7 @@ def self.values_for_permissions
50
53
  key = 'helpers.label.dc_policy_rule.choices4_permission'
51
54
  c = I18n.t(key)
52
55
  c = I18n.t(key, locale: 'en') if c.class == Hash or c.match( 'translation missing' )
53
- c.split(',').inject([]) {|r,e| r << (ar = e.split(':'); [ar.first, ar.last.to_i]) }
56
+ c.split(',').inject([]) { |r,e| r << (ar = e.split(':'); [ar.first, ar.last.to_i]) }
54
57
  end
55
58
 
56
59
  #########################################################################
@@ -74,5 +77,14 @@ def self.permission_name_for_value(value)
74
77
  'error'
75
78
  end
76
79
 
80
+ private
81
+
82
+ ####################################################################
83
+ # Clear cache if cache is configured
84
+ ####################################################################
85
+ def cache_clear
86
+ _parent.send(:cache_clear) if _parent.respond_to?(:cache_clear)
87
+ end
88
+
77
89
  end
78
90
  end
@@ -0,0 +1,66 @@
1
+ #--
2
+ # Copyright (c) 2019+ 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
+ # dc_seo_concern, ads SEO optimization fields to any model.
26
+ #
27
+ # title String Browser title. Optimization for SEO.
28
+ # meta_description String SEO optimised page description
29
+ # meta_additional String Additional meta page data. Enter as meta_name=meta data
30
+ # dc_json_lds Embedded:DcJsonLd Page structure data
31
+ #
32
+ # If you want to add SEO optimization data to your document add:
33
+ #
34
+ # "include DcSeoConcern" to your model definition
35
+ #
36
+ # and
37
+ #
38
+ # "include: dc_seo" option to top of DRGCMS edit form for your document.
39
+ ##########################################################################
40
+ module DcSeoConcern
41
+ extend ActiveSupport::Concern
42
+
43
+ included do
44
+ field :title, type: String
45
+ field :meta_description, type: String
46
+ field :canonical_link, type: String
47
+ embeds_many :dc_json_lds # JSON-LD structure
48
+
49
+ ######################################################################
50
+ # Will return JSON LD data if defined for the page
51
+ ######################################################################
52
+ def get_json_ld()
53
+ parent_data = {'datePublished' => self.created_at, 'dateModified' => self.updated_at}
54
+ data = []
55
+ if dc_json_lds.size > 0
56
+ dc_json_lds.where(active: true).each do |element|
57
+ dta = element.get_json_ld(parent_data)
58
+ data << dta if dta.size > 0
59
+ end
60
+ end
61
+ data
62
+ end
63
+ end
64
+
65
+
66
+ end
@@ -27,44 +27,55 @@
27
27
  module DcSiteConcern
28
28
  extend ActiveSupport::Concern
29
29
  included do
30
- include Mongoid::Document
31
- include Mongoid::Timestamps
32
-
33
- field :name, type: String
34
- field :description, type: String
35
- field :homepage_link, type: String
36
- field :error_link, type: String
37
- field :header, type: String, default: ''
38
- field :css, type: String, default: ''
39
- field :route_name, type: String, default: ''
40
- field :page_title, type: String
41
- field :document_extension, type: String
42
- field :page_table, type: String
43
- field :page_class, type: String, default: 'DcPage'
44
- field :site_layout, type: String, default: 'content'
45
- field :menu_class, type: String, default: 'DcSimpleMenu'
46
- field :request_processor, type: String
47
- field :files_directory, type: String
48
- field :logo, type: String
49
- field :active, type: Boolean, default: true
50
- field :created_by, type: BSON::ObjectId
51
- field :updated_by, type: BSON::ObjectId
52
- field :menu_name, type: String
53
- field :menu_id, type: BSON::ObjectId
54
- field :settings, type: String
55
- field :alias_for, type: String
56
- field :rails_view, type: String, default: ''
57
- field :design, type: String, default: ''
58
- field :inherit_policy, type: BSON::ObjectId
59
-
60
- embeds_many :dc_policies
61
- embeds_many :dc_parts
62
-
63
- index( { name: 1 }, { unique: true } )
64
- index( { alias_for: 1 } )
65
-
66
- validates :name, presence: true
67
- validates :name, uniqueness: true
30
+
31
+ include Mongoid::Document
32
+ include Mongoid::Timestamps
33
+
34
+ field :name, type: String
35
+ field :description, type: String
36
+ field :homepage_link, type: String
37
+ field :error_link, type: String
38
+ field :header, type: String, default: ''
39
+ field :css, type: String, default: ''
40
+ field :route_name, type: String, default: ''
41
+ field :page_title, type: String
42
+ field :document_extension, type: String
43
+ field :page_table, type: String
44
+ field :page_class, type: String, default: 'DcPage'
45
+ field :site_layout, type: String, default: 'content'
46
+ field :menu_class, type: String, default: 'DcSimpleMenu'
47
+ field :request_processor, type: String
48
+ field :files_directory, type: String
49
+ field :logo, type: String
50
+ field :active, type: Boolean, default: true
51
+ field :created_by, type: BSON::ObjectId
52
+ field :updated_by, type: BSON::ObjectId
53
+ field :menu_name, type: String
54
+ field :menu_id, type: BSON::ObjectId
55
+ field :settings, type: String
56
+ field :alias_for, type: String
57
+ field :rails_view, type: String, default: ''
58
+ field :design, type: String, default: ''
59
+ field :inherit_policy, type: BSON::ObjectId
60
+
61
+ embeds_many :dc_policies
62
+ embeds_many :dc_parts
63
+
64
+ index( { name: 1 }, { unique: true } )
65
+ index( { alias_for: 1 } )
66
+
67
+ validates :name, presence: true
68
+ validates :name, uniqueness: true
69
+
70
+ after_save :cache_clear
71
+ after_destroy :cache_clear
72
+
73
+ ####################################################################
74
+ # Clear cache if cache is configured
75
+ ####################################################################
76
+ def cache_clear
77
+ DrgCms.cache_clear(:dc_site)
78
+ end
68
79
 
69
80
  ########################################################################
70
81
  # Returns value of site setting. If no value is send as parameter it returns
@@ -78,15 +89,15 @@ end
78
89
  ########################################################################
79
90
  # Returns class object of collection name
80
91
  ########################################################################
81
- def page_klass()
92
+ def page_klass
82
93
  (self.page_table.blank? ? self.page_class : self.page_table).classify.constantize
83
94
  end
84
95
 
85
96
  ########################################################################
86
97
  # Returns class object of menu collection name
87
98
  ########################################################################
88
- def menu_klass()
89
- (self.menu_class.blank? ? 'DcMenu' : self.menu_class).classify.constantize
99
+ def menu_klass
100
+ (menu_class.blank? ? 'DcMenu' : menu_class).classify.constantize
90
101
  end
91
102
 
92
103
  ########################################################################
@@ -99,11 +110,23 @@ end
99
110
 
100
111
  ########################################################################
101
112
  # Return choices for selecting policies for the site
113
+ # @deprecated
102
114
  ########################################################################
103
- def self.choices4_policies
104
- site = ApplicationController.dc_get_site_()
115
+ #def self.choices4_policies
116
+ # site = ApplicationController.dc_get_site_()
105
117
  #all.inject([]) { |r,site| r << [ (site.active ? '' : t('drgcms.disabled') ) + site.name, site._id] }
106
- [['a','b']]
118
+ # [['a','b']]
119
+ #end
120
+
121
+ ########################################################################
122
+ # Return choices for selecting policies for the site
123
+ ########################################################################
124
+ def self.choices_for_menu(menu_class)
125
+ return [] if menu_class.blank?
126
+ menu = menu_class.classify.constantize
127
+ menu.where(active: true).inject([]) do |r, a_menu|
128
+ r << [a_menu.description, a_menu.id]
129
+ end
107
130
  end
108
131
 
109
132
  end
@@ -56,8 +56,8 @@ field :valid_to, type: Date
56
56
  field :created_by, type: BSON::ObjectId
57
57
  field :updated_by, type: BSON::ObjectId
58
58
 
59
- field :type, type: Integer, default: 0 # 0 => User, 1 => Group
60
- field :members, type: Array
59
+ field :group, type: Boolean, default: false # false => User, true => Group
60
+ field :member, type: Array
61
61
 
62
62
  embeds_many :dc_user_roles
63
63
 
@@ -73,23 +73,17 @@ has_secure_password
73
73
 
74
74
  index( { username: 1 }, { unique: true } )
75
75
  index( { email: 1 }, { unique: true } )
76
- index 'dc_user_roles.dc_policy_role_id' => 1
77
- index 'members' => 1
76
+ index 'dc_user_roles.dc_policy_role_id' => 1
77
+ index member: 1
78
+ index group: 1
78
79
 
79
80
  validates_length_of :username, minimum: 4
80
81
  validates :username, uniqueness: true
81
- validates :email, uniqueness: true
82
- before_save :do_before_save
82
+ validates :email, uniqueness: true
83
+ validate :do_validate
83
84
 
84
- ##########################################################################
85
- # before_save callback takes care of name field and ensures that e-mail is unique
86
- # when entry is left empty.
87
- ##########################################################################
88
- def do_before_save
89
- self.name = "#{self.title} #{self.first_name} #{self.middle_name + ' ' unless self.middle_name.blank?}#{self.last_name}".strip
90
- # to ensure unique e-mail
91
- self.email = "unknown@#{self.id}" if self.email.to_s.strip.size < 5
92
- end
85
+ before_save :do_before_save
86
+ before_validation :do_before_validation
93
87
 
94
88
  ##########################################################################
95
89
  # Checks if user has role 'role_id' defined in his roles.
@@ -98,7 +92,7 @@ end
98
92
  ##########################################################################
99
93
  def has_role?(role_id)
100
94
  return false unless role_id
101
- #
95
+
102
96
  unless BSON::ObjectId.legal?(role_id)
103
97
  role = DcPolicyRole.get_role(role_id)
104
98
  role_id = role.id if role
@@ -111,7 +105,7 @@ end
111
105
  # Will return all possible values for country field ready for input in select field.
112
106
  # Values are loaded from github when method is first called.
113
107
  ##########################################################################
114
- def self.choices4_country()
108
+ def self.choices4_country
115
109
  if @@countries.nil?
116
110
  uri = URI.parse("https://raw.githubusercontent.com/umpirsky/country-list/master/country/cldr/en/country.json")
117
111
  http = Net::HTTP.new(uri.host, uri.port)
@@ -125,7 +119,7 @@ def self.choices4_country()
125
119
  end
126
120
 
127
121
  ##########################################################################
128
- # Performs ligically test on passed email parameter.
122
+ # Performs logically test on passed email parameter.
129
123
  #
130
124
  # Parameters:
131
125
  # [email] String: e-mail address
@@ -143,5 +137,50 @@ def self.is_email?(email)
143
137
  email.to_s =~ /^[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/
144
138
  end
145
139
 
140
+ ##########################################################################
141
+ # Will return list of available groups
142
+ ##########################################################################
143
+ def self.groups_for_select
144
+ where(group: true, active: true).order_by(name: 1).inject([]) { |r, e| r << [e.name, e.id] }
145
+ end
146
+
147
+ private
148
+
149
+ ##########################################################################
150
+ # before_save callback takes care of name field and ensures that e-mail is unique
151
+ # when entry is left empty.
152
+ ##########################################################################
153
+ def do_before_save
154
+ self.name = "#{title} #{first_name} #{middle_name + ' ' unless middle_name.blank?}#{last_name}".strip
155
+ # to ensure unique e-mail
156
+ self.email = "unknown@#{id}" if email.blank?
157
+ end
158
+
159
+ ##########################################################################
160
+ # Create random password for groups. Must be done before validation
161
+ ##########################################################################
162
+ def do_before_validation
163
+ if new_record? && group
164
+ self.password = DcUser.random_password(30)
165
+ self.password_confirmation = password
166
+ end
167
+ end
168
+
169
+ ##########################################################################
170
+ # Perform some additional validations
171
+ ##########################################################################
172
+ def do_validate
173
+ if group && member.present?
174
+ errors.add('member', I18n.t('errors.messages.present'))
175
+ end
176
+ end
177
+ ##########################################################################
178
+ # Will create random password
179
+ ##########################################################################
180
+ def self.random_password(number)
181
+ charset = Array('A'..'Z') + Array('0'..'9') + Array('a'..'z')
182
+ Array.new(number) { charset.sample }.join
183
+ end
184
+
146
185
  end
147
186
  end