drg_cms 0.4.39

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 (204) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +39 -0
  5. data/app/assets/images/drg_cms/add.png +0 -0
  6. data/app/assets/images/drg_cms/arrow_in.png +0 -0
  7. data/app/assets/images/drg_cms/arrow_out.png +0 -0
  8. data/app/assets/images/drg_cms/checkbox-checked.png +0 -0
  9. data/app/assets/images/drg_cms/checkbox-unchecked.png +0 -0
  10. data/app/assets/images/drg_cms/cols.png +0 -0
  11. data/app/assets/images/drg_cms/copy.png +0 -0
  12. data/app/assets/images/drg_cms/edit.png +0 -0
  13. data/app/assets/images/drg_cms/edit_design.png +0 -0
  14. data/app/assets/images/drg_cms/edit_page.png +0 -0
  15. data/app/assets/images/drg_cms/edit_site.png +0 -0
  16. data/app/assets/images/drg_cms/html.png +0 -0
  17. data/app/assets/images/drg_cms/pin.png +0 -0
  18. data/app/assets/images/drg_cms/printer.png +0 -0
  19. data/app/assets/images/drg_cms/reload.png +0 -0
  20. data/app/assets/images/drg_cms/search_16.png +0 -0
  21. data/app/assets/images/drg_cms/spinner.gif +0 -0
  22. data/app/assets/images/drg_cms/view_tile.png +0 -0
  23. data/app/assets/images/drg_cms/x.png +0 -0
  24. data/app/assets/javascripts/drg_cms/drg_cms.js +449 -0
  25. data/app/assets/javascripts/drg_cms/jquery-migrate.js +511 -0
  26. data/app/assets/javascripts/drg_cms/jquery.datetimepicker.js +1353 -0
  27. data/app/assets/javascripts/drg_cms/some_scripts.js +33 -0
  28. data/app/assets/javascripts/drg_cms_application.js +11 -0
  29. data/app/assets/javascripts/drg_cms_cms.js +28 -0
  30. data/app/assets/stylesheets/drg_cms/drg_cms.css +632 -0
  31. data/app/assets/stylesheets/drg_cms/jquery-ui.css +339 -0
  32. data/app/assets/stylesheets/drg_cms/jquery.datetimepicker.css +304 -0
  33. data/app/assets/stylesheets/drg_cms/th-bg.png +0 -0
  34. data/app/assets/stylesheets/drg_cms/theme.css +49 -0
  35. data/app/assets/stylesheets/drg_cms_application.css +12 -0
  36. data/app/assets/stylesheets/drg_cms_cms.css +26 -0
  37. data/app/controllers/cmsedit_controller.rb +673 -0
  38. data/app/controllers/dc_application_controller.rb +385 -0
  39. data/app/controllers/dc_at_the_beginning_controller.rb +120 -0
  40. data/app/controllers/dc_common_controller.rb +314 -0
  41. data/app/controllers/dc_mail_controller.rb +89 -0
  42. data/app/controllers/dc_main_controller.rb +40 -0
  43. data/app/controllers/drgcms_controls/dc_page_controls.rb +40 -0
  44. data/app/forms/all_options.yml +176 -0
  45. data/app/forms/cms_forms.yml +93 -0
  46. data/app/forms/cms_menu.yml +142 -0
  47. data/app/forms/dc_ad.yml +130 -0
  48. data/app/forms/dc_big_table.yml +59 -0
  49. data/app/forms/dc_big_table_locale.yml +41 -0
  50. data/app/forms/dc_big_table_value.yml +47 -0
  51. data/app/forms/dc_category.yml +57 -0
  52. data/app/forms/dc_design.yml +68 -0
  53. data/app/forms/dc_folder_permission.yml +49 -0
  54. data/app/forms/dc_forum_cat.yml +54 -0
  55. data/app/forms/dc_forum_forum.yml +53 -0
  56. data/app/forms/dc_forum_msg.yml +124 -0
  57. data/app/forms/dc_forum_privmsg.yml +125 -0
  58. data/app/forms/dc_forum_topic.yml +131 -0
  59. data/app/forms/dc_journal.yml +85 -0
  60. data/app/forms/dc_link.yml +55 -0
  61. data/app/forms/dc_mail.yml +88 -0
  62. data/app/forms/dc_mail_address.yml +56 -0
  63. data/app/forms/dc_mail_list.yml +44 -0
  64. data/app/forms/dc_mail_list_member.yml +42 -0
  65. data/app/forms/dc_menu.yml +62 -0
  66. data/app/forms/dc_menu_item.yml +81 -0
  67. data/app/forms/dc_page.yml +145 -0
  68. data/app/forms/dc_part.yml +102 -0
  69. data/app/forms/dc_permission.yml +50 -0
  70. data/app/forms/dc_piece.yml +105 -0
  71. data/app/forms/dc_policy.yml +57 -0
  72. data/app/forms/dc_policy_role.yml +42 -0
  73. data/app/forms/dc_policy_rule.yml +38 -0
  74. data/app/forms/dc_policy_rule_nocms.yml +38 -0
  75. data/app/forms/dc_poll.yml +113 -0
  76. data/app/forms/dc_poll_item.yml +76 -0
  77. data/app/forms/dc_simple_menu.yml +64 -0
  78. data/app/forms/dc_simple_menu_item.yml +80 -0
  79. data/app/forms/dc_site.yml +149 -0
  80. data/app/forms/dc_user.yml +142 -0
  81. data/app/forms/dc_user_role.yml +54 -0
  82. data/app/forms/drgcms_cms.yml +28 -0
  83. data/app/helpers/cmsedit_helper.rb +698 -0
  84. data/app/helpers/dc_ad_renderer.rb +206 -0
  85. data/app/helpers/dc_application_helper.rb +704 -0
  86. data/app/helpers/dc_big_menu_renderer.rb +180 -0
  87. data/app/helpers/dc_captcha_renderer.rb +100 -0
  88. data/app/helpers/dc_common_renderer.rb +132 -0
  89. data/app/helpers/dc_mail_renderer.rb +76 -0
  90. data/app/helpers/dc_menu_renderer.rb +143 -0
  91. data/app/helpers/dc_page_renderer.rb +80 -0
  92. data/app/helpers/dc_part_renderer.rb +162 -0
  93. data/app/helpers/dc_piece_renderer.rb +124 -0
  94. data/app/helpers/dc_poll_renderer.rb +219 -0
  95. data/app/helpers/dc_renderer.rb +56 -0
  96. data/app/helpers/dc_simple_menu_renderer.rb +244 -0
  97. data/app/helpers/drgcms_form_field.rb +863 -0
  98. data/app/models/__dc_global_data.rb +44 -0
  99. data/app/models/dc_ad.rb +52 -0
  100. data/app/models/dc_ad_stat.rb +34 -0
  101. data/app/models/dc_big_menu.rb +89 -0
  102. data/app/models/dc_big_table.rb +63 -0
  103. data/app/models/dc_big_table_locale.rb +35 -0
  104. data/app/models/dc_big_table_value.rb +38 -0
  105. data/app/models/dc_category.rb +48 -0
  106. data/app/models/dc_design.rb +48 -0
  107. data/app/models/dc_dummy.rb +30 -0
  108. data/app/models/dc_folder_permission.rb +43 -0
  109. data/app/models/dc_global_data.rb +44 -0
  110. data/app/models/dc_journal.rb +39 -0
  111. data/app/models/dc_key_value_store.rb +90 -0
  112. data/app/models/dc_link.rb +39 -0
  113. data/app/models/dc_mail.rb +64 -0
  114. data/app/models/dc_mail_address.rb +69 -0
  115. data/app/models/dc_mail_list.rb +48 -0
  116. data/app/models/dc_mail_list_member.rb +34 -0
  117. data/app/models/dc_menu.rb +59 -0
  118. data/app/models/dc_menu_item.rb +40 -0
  119. data/app/models/dc_page.rb +123 -0
  120. data/app/models/dc_part.rb +28 -0
  121. data/app/models/dc_permission.rb +58 -0
  122. data/app/models/dc_piece.rb +57 -0
  123. data/app/models/dc_policy.rb +94 -0
  124. data/app/models/dc_policy_role.rb +47 -0
  125. data/app/models/dc_policy_rule.rb +65 -0
  126. data/app/models/dc_poll.rb +46 -0
  127. data/app/models/dc_poll_item.rb +40 -0
  128. data/app/models/dc_sendmail.rb +48 -0
  129. data/app/models/dc_simple_menu.rb +58 -0
  130. data/app/models/dc_simple_menu_item.rb +39 -0
  131. data/app/models/dc_site.rb +92 -0
  132. data/app/models/dc_stat.rb +36 -0
  133. data/app/models/dc_user.rb +91 -0
  134. data/app/models/dc_user_role.rb +36 -0
  135. data/app/models/dc_visit.rb +35 -0
  136. data/app/views/cmsedit/_edit_stuff.html.erb +59 -0
  137. data/app/views/cmsedit/_edit_stuff.js.erb +6 -0
  138. data/app/views/cmsedit/_form.html.erb +21 -0
  139. data/app/views/cmsedit/_result.html.erb +20 -0
  140. data/app/views/cmsedit/edit.html.erb +6 -0
  141. data/app/views/cmsedit/error.html.erb +2 -0
  142. data/app/views/cmsedit/index.html.erb +6 -0
  143. data/app/views/cmsedit/new.html.erb +5 -0
  144. data/app/views/cmsedit/show.html.erb +21 -0
  145. data/app/views/dc_at_the_beginning/create.html.erb +9 -0
  146. data/app/views/dc_at_the_beginning/index.html.erb +19 -0
  147. data/app/views/dc_common/paste_clipboard.html.erb +17 -0
  148. data/app/views/dc_mail/subscribe.html.erb +7 -0
  149. data/app/views/dc_mail/unsubscribe.html.erb +19 -0
  150. data/app/views/layouts/cms.html.erb +17 -0
  151. data/app/views/layouts/cmsedit.html.erb +16 -0
  152. data/app/views/layouts/content.html.erb +16 -0
  153. data/config/initializers/kaminari_patch.rb +36 -0
  154. data/config/locales/datetimepicker.yml +13 -0
  155. data/config/locales/drgcms_en.yml +96 -0
  156. data/config/locales/drgcms_sl.yml +97 -0
  157. data/config/locales/en.yml +7 -0
  158. data/config/locales/kaminari.yml +26 -0
  159. data/config/locales/models_en.yml +790 -0
  160. data/config/locales/models_sl.yml +805 -0
  161. data/config/locales/mongoid_sl.yml +60 -0
  162. data/config/locales/sl.yml +211 -0
  163. data/config/routes.rb +2 -0
  164. data/drg_cms.gemspec +28 -0
  165. data/lib/drg_cms.rb +45 -0
  166. data/lib/drg_cms/engine.rb +30 -0
  167. data/lib/drg_cms/version.rb +3 -0
  168. data/lib/tasks/at_the_beginning.yml +26 -0
  169. data/lib/tasks/dc_cleanup.rake +94 -0
  170. data/lib/tasks/drg_cms_tasks.rake +118 -0
  171. data/lib/tasks/send_mail.rake +253 -0
  172. data/lib/tasks/site_statistics.rake +80 -0
  173. data/test/drg_cms_test.rb +7 -0
  174. data/test/dummy/README.rdoc +261 -0
  175. data/test/dummy/Rakefile +7 -0
  176. data/test/dummy/app/assets/javascripts/application.js +15 -0
  177. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  178. data/test/dummy/app/controllers/application_controller.rb +3 -0
  179. data/test/dummy/app/helpers/application_helper.rb +2 -0
  180. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  181. data/test/dummy/config.ru +4 -0
  182. data/test/dummy/config/application.rb +59 -0
  183. data/test/dummy/config/boot.rb +10 -0
  184. data/test/dummy/config/database.yml +25 -0
  185. data/test/dummy/config/environment.rb +5 -0
  186. data/test/dummy/config/environments/development.rb +37 -0
  187. data/test/dummy/config/environments/production.rb +67 -0
  188. data/test/dummy/config/environments/test.rb +37 -0
  189. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  190. data/test/dummy/config/initializers/inflections.rb +15 -0
  191. data/test/dummy/config/initializers/mime_types.rb +5 -0
  192. data/test/dummy/config/initializers/secret_token.rb +7 -0
  193. data/test/dummy/config/initializers/session_store.rb +8 -0
  194. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  195. data/test/dummy/config/locales/en.yml +5 -0
  196. data/test/dummy/config/routes.rb +58 -0
  197. data/test/dummy/public/404.html +26 -0
  198. data/test/dummy/public/422.html +26 -0
  199. data/test/dummy/public/500.html +25 -0
  200. data/test/dummy/public/favicon.ico +0 -0
  201. data/test/dummy/script/rails +6 -0
  202. data/test/integration/navigation_test.rb +10 -0
  203. data/test/test_helper.rb +15 -0
  204. metadata +375 -0
@@ -0,0 +1,206 @@
1
+ #--
2
+ # Copyright (c) 2012-2013 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 BUTe 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
+ ########################################################################
27
+ class DcAdRenderer
28
+
29
+ include DcApplicationHelper
30
+
31
+ ########################################################################
32
+ #
33
+ ########################################################################
34
+ def initialize( parent, opts={} )
35
+ @parent = parent
36
+ @opts = opts
37
+ @css = ''
38
+ self
39
+ end
40
+
41
+ ########################################################################
42
+ #
43
+ ########################################################################
44
+ def find_ads_multi()
45
+ ads = DcAd.where( position: @opts[:position], active: true).to_a#, :valid_to.gt => Time.now, :valid_from.lt => Time.now).to_a
46
+ #p @opts, ads.size, '*-*-*-*'
47
+ ads.delete_if { |ad| (ad.valid_to and ad.valid_to < Time.now) or
48
+ (ad.valid_from and ad.valid_from > Time.now) or
49
+ (ad.displays > 0 and ad.displayed >= ad.displays) or
50
+ (ad.clicks > 0 and ad.clicked >= ad.clicks) }
51
+
52
+ ads
53
+ end
54
+
55
+ ########################################################################
56
+ # Default method for rendering ads
57
+ ########################################################################
58
+ def multi
59
+ return '' if @parent.session[:is_robot] # don't bother if robot
60
+ html = "<div id='ad-#{@opts[:position]}-div'>"
61
+ n = 0
62
+ find_ads_multi.each do |ad|
63
+ div = "ad-#{@opts[:position]}-#{n+=1}"
64
+ html << "<div id='#{div}' style='position: absolute; display: none;'>"
65
+ # all except first are hidden
66
+ # html << n == 1 ? '>' : 'style="display: none;">'
67
+ html << case ad.type
68
+ when 1 then # picture
69
+ picture_link ad
70
+ when 2 then # flash
71
+ flash_link ad
72
+ when 3 then # script
73
+ ad.script
74
+ else
75
+ 'Error. Wrong ad type!'
76
+ end
77
+ html << '</div>'
78
+ end
79
+ #
80
+ html << '</div>'
81
+ if n > 0
82
+ js = <<EOJS
83
+ dc_ad_next_slide = function(div, index, max, timeout) {
84
+ index = index + 1;
85
+ div_show = div + index.toString();
86
+ index_h = index - 1;
87
+ if (index_h == 0) index_h = max;
88
+ div_hide = div + index_h.toString();
89
+ $('#' + div_show).fadeIn(1500);
90
+ $('#' + div_hide).fadeOut(1500);
91
+
92
+ if (index == max) index = 0;
93
+ setTimeout( function () { dc_ad_next_slide(div, index, max, timeout); }, timeout);
94
+ }
95
+
96
+ $(document).ready(function () {
97
+ dc_ad_next_slide("ad-#{@opts[:position]}-", 0, #{n}, 5000)
98
+ });
99
+ EOJS
100
+ html << @parent.javascript_tag(js)
101
+ end
102
+ html
103
+ end
104
+
105
+ ########################################################################
106
+ #
107
+ ########################################################################
108
+ def find_ad_to_display()
109
+ ads = DcAd.where( dc_site_id: @parent.site._id, position: @opts[:position], active: true).to_a#, :valid_to.gt => Time.now, :valid_from.lt => Time.now).to_a
110
+ #p @opts, ads.size, '*-*-*-*'
111
+ ads.delete_if { |ad| (ad.valid_to and ad.valid_to < Time.now) or
112
+ (ad.valid_from and ad.valid_from > Time.now) or
113
+ (ad.displays > 0 and ad.displayed >= ad.displays) or
114
+ (ad.clicks > 0 and ad.clicked >= ad.clicks) }
115
+ return nil if ads.size == 0
116
+ # Determine ad to display, based on priority. This is of course not totaly accurate,
117
+ # but it will have to do.
118
+ sum = ads.inject(0) {|r, e| r += e.priority}
119
+ rnd = Random.rand(sum)
120
+ r = 0
121
+ ads.each do |e|
122
+ return e if rnd >= r and rnd < r + e.priority
123
+ r += e.priority
124
+ end
125
+ ads.last # we really shouldn't be here
126
+ end
127
+
128
+ ########################################################################
129
+ # Create flash link for ad
130
+ ########################################################################
131
+ def flash_link(ad)
132
+ click_tag = ad.link.to_s.size > 5 ? "flashvars=\"clickTag=#{ad.link}\"" : ''
133
+ <<EOT
134
+ <div class="link_to_track" id="#{ad.id}">
135
+ <object>
136
+ <param name="wmode" value="transparent" />
137
+ <embed width="#{ad.width}" height="#{ad.height}" src="#{ad.file}" #{click_tag}
138
+ wmode=transparent allowfullscreen='true' allowscriptaccess='always' type="application/x-shockwave-flash"></embed>
139
+ </object>
140
+ </div>
141
+
142
+ <script type='text/javascript'>
143
+ $('##{ad.id}').mousedown(function (e){
144
+ $.post('/dc_common/ad_click', { id: this.id });
145
+ return true;
146
+ });
147
+ </script>
148
+ EOT
149
+ end
150
+
151
+ ########################################################################
152
+ # Create picture link for ad
153
+ ########################################################################
154
+ def picture_link(ad)
155
+ @parent.link_to @parent.image_tag(ad.file), ad.link, id: ad.id, class: 'link_to_track', target: ad.link_target
156
+ end
157
+
158
+ ########################################################################
159
+ # Default method for rendering ads
160
+ ########################################################################
161
+ def default
162
+ return '' if @parent.session[:is_robot] # don't bother if robot
163
+ html = ''
164
+ if (ad = find_ad_to_display)
165
+ # save to statistics, if not in cms
166
+ if @opts[:edit_mode] < 1
167
+ DcAdStat.create!(dc_ad_id: ad.id, ip: @parent.request.ip, type: 1 )
168
+ # save display counter
169
+ ad.displayed += 1
170
+ ad.save
171
+ end
172
+ html << case ad.type
173
+ when 1 then # picture
174
+ picture_link ad
175
+ when 2 then # flash
176
+ flash_link ad
177
+ when 3 then # script
178
+ ad.script
179
+ else
180
+ 'Error. Wrong ad type!'
181
+ end
182
+ end
183
+ html
184
+ end
185
+
186
+ ########################################################################
187
+ # Render HTML
188
+ ########################################################################
189
+ def render_html
190
+ method = @opts[:method] || 'default'
191
+ html = if method and self.respond_to?(method)
192
+ send(method)
193
+ else
194
+ "DcAdRenderer: method #{method} not defined!"
195
+ end
196
+ html
197
+ end
198
+
199
+ ########################################################################
200
+ # Render CSS
201
+ ########################################################################
202
+ def render_css
203
+ @css
204
+ end
205
+
206
+ end
@@ -0,0 +1,704 @@
1
+ #coding: utf-8
2
+ #--
3
+ # Copyright (c) 2012+ Damjan Rems
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #++
24
+
25
+ module DcApplicationHelper
26
+ attr_reader :page, :design, :site, :tables, :ids, :form, :options
27
+ attr_accessor :parts
28
+
29
+ ############################################################################
30
+ # Calls part renderer to return part of design.
31
+ ############################################################################
32
+ def dc_render(renderer, opts={})
33
+ type = renderer.to_s.downcase
34
+ opts[:edit_mode] = session[:edit_mode]
35
+ # TODO Check why did I always put return_to into link and will this break something
36
+ # opts[:editparams] = { return_to: request.url }
37
+ opts[:editparams] = {}
38
+ opts = @options.merge(opts) # merge options with parameters passed on site, page, design ...
39
+ opts.symbolize_keys! # this makes lots of things easier
40
+ # Create renderer object
41
+ klass = (type + '_renderer').classify
42
+ obj = Kernel.const_get(klass, Class.new).new(self, opts)
43
+ #
44
+ html = obj.render_html
45
+ @css << obj.render_css.to_s
46
+ html.nil? ? '' : html.html_safe # nil can happened
47
+ end
48
+
49
+ ########################################################################
50
+ # Used for designs with lots of common code and one part which is different.
51
+ #
52
+ # Example: As used in design. Backslashing < and % is important \<\%
53
+ # <% part = "<div class='some-class'>\<\%= dc_render(:my_renderer, method: 'render_method') \%\></div>" %>
54
+ # <%= dc_replace_in_design(piece: 'piece_name', replace: '[main]', with: part) %>
55
+ #
56
+ # Want to replace more than one part. Use array.
57
+ # <%= dc_replace_in_design(replace: ['[part1]','[part2]'], with: [part1, part2]) %>
58
+ #
59
+ # This helper is replacement for 'script' method defined in dc_piece_renderer,
60
+ # but it can also use design defined in site document if piece parameter is not set.
61
+ ########################################################################
62
+ def dc_replace_in_design(opts={})
63
+ design = opts[:piece] ? DcPiece.find(name: opts[:piece]).script : dc_get_site.design
64
+ if opts[:replace]
65
+ # replace more than one part of code
66
+ if opts[:replace].class == Array
67
+ 0.upto(opts[:replace].size - 1) {|i| design.sub!(opts[:replace][i], opts[:with][i])}
68
+ else
69
+ design.sub!(opts[:replace], opts[:with])
70
+ end
71
+ end
72
+ render(inline: design, layout: opts[:layout])
73
+ end
74
+
75
+ ########################################################################
76
+ ########################################################################
77
+ def dc_render_design(opts={}) #NODOC
78
+ p "dc_render_design will be deprecated. Use dc_replace_in_design instead."
79
+ dc_replace_in_design(opts)
80
+ end
81
+
82
+ ############################################################################
83
+ # Creates title for dialog. Title also has pagination link on its right side.
84
+ ############################################################################
85
+ def dc_table_title(text, result=nil)
86
+ c = "<table width='100%' cellspacing='0' cellpadding='1' class='dc-title'><tr><td>#{text}</td>"
87
+ if result and result.respond_to?(:current_page)
88
+ c << "<td align='right' style='font-size: 0.8em;'> #{paginate(result, :params => {:action => 'index'})}</td>"
89
+ end
90
+ c << '<tr></table>'
91
+ c.html_safe
92
+ end
93
+
94
+ ############################################################################
95
+ # Creates title for cmsedit edit dialog.
96
+ ############################################################################
97
+ def dc_edit_title()
98
+ c = "#{t('drgcms.edit')} : "
99
+ c << (@form['title'] ? t( @form['title'], @form['title'] ) : t_tablename(@form['table'])) + ' : '
100
+ title = @form['form']['edit_title'] || @form['edit_title'] # edit_title bo šel ven
101
+ c << "#{@record[ title ]} : " if title and @record.respond_to?(title)
102
+ c << @record._id
103
+ end
104
+
105
+ ############################################################################
106
+ # Creates title for cmsedit new dialog.
107
+ ############################################################################
108
+ def dc_new_title()
109
+ if @form['table'] == 'dc_dummy'
110
+ t( @form['title'], @form['title'] )
111
+ else
112
+ "#{t('drgcms.new')} : #{t_tablename(@form['table'])}"
113
+ end
114
+ end
115
+
116
+ ####################################################################
117
+ # Creates label for edit dialog.
118
+ ####################################################################
119
+ def dc_label_for(input_html, label)
120
+ c =<<eot
121
+ <tr>
122
+ <td class="dc-edit-label">#{label}</td>
123
+ <td class="dc-edit-field">#{input_html}</td>
124
+ </tr>
125
+ eot
126
+ c.html_safe
127
+ end
128
+
129
+ ####################################################################
130
+ # Returns messages saved in flash formated for display.
131
+ ####################################################################
132
+ def dc_flash_messages()
133
+ err = @parent ? @parent.flash[:error] : flash[:error]
134
+ war = @parent ? @parent.flash[:warning] : flash[:warning]
135
+ inf = @parent ? @parent.flash[:info] : flash[:info]
136
+ note = @parent ? @parent.flash[:note] : flash[:note]
137
+ unless err.nil? and war.nil? and inf.nil? and note.nil?
138
+ c = ''
139
+ c << "<div class=\"dc-form-error\">#{err}</div>" if err
140
+ c << "<div class=\"dc-form-warning\">#{war}</div>" if war
141
+ c << "<div class=\"dc-form-info\">#{inf}</div>" if inf
142
+ c << note if note
143
+ if @parent
144
+ @parent.flash[:error] = nil
145
+ @parent.flash[:warning] = nil
146
+ @parent.flash[:info] = nil
147
+ @parent.flash[:note] = nil
148
+ else
149
+ flash[:error] = nil
150
+ flash[:warning] = nil
151
+ flash[:info] = nil
152
+ flash[:note] = nil
153
+ end
154
+ c.html_safe
155
+ end
156
+ end
157
+
158
+ ########################################################################
159
+ # Decamelizes string. This probably doesn't work very good with non ascii chars.
160
+ # Therefore it is very unwise to use non ascii chars for table (collection) names.
161
+ ########################################################################
162
+ def decamelize_type(st)
163
+ return nil if st.nil?
164
+ r = ''
165
+ st.to_s.each_char do |c|
166
+ r << case
167
+ when r.size == 0 then c.downcase
168
+ when c.downcase != c then '_' + c.downcase
169
+ else c
170
+ end
171
+ end
172
+ r
173
+ end
174
+
175
+ ####################################################################
176
+ # return error messages for the record
177
+ ####################################################################
178
+ def dc_error_messages_for(r)
179
+ return '' unless r.errors.any?
180
+ msgs = ''
181
+ r.errors.each do |attribute, errors_array|
182
+ label = t("helpers.label.#{decamelize_type(r.class)}.#{attribute}", attribute)
183
+ msgs << "<li>#{label} : #{errors_array}</li>"
184
+ end
185
+
186
+ c = <<eot
187
+ <div class="dc-form-error">
188
+ <h2>#{t('drgcms.errors_no')} #{r.errors.size}</h2>
189
+ <ul>#{msgs}</ul>
190
+ </div>
191
+ eot
192
+ c.html_safe
193
+ end
194
+
195
+ ####################################################################
196
+ # return true if in edit mode
197
+ ####################################################################
198
+ def dc_edit_mode?
199
+ (@parent ? @parent.session[:edit_mode] : session[:edit_mode]) > 1
200
+ end
201
+
202
+ ####################################################################
203
+ # Return create link for drg_cms
204
+ ####################################################################
205
+ def dc_link_for_create(opts)
206
+ title = opts.delete(:title) #
207
+ target = opts.delete(:target) || 'iframe_cms'
208
+ opts[:action] = 'new'
209
+ url = @parent ? @parent.url_for(opts) : url_for(opts)
210
+ js = "$('##{target}').attr('src', '#{url}'); return false;"
211
+ html = if @parent
212
+ @parent.image_tag('drg_cms/add.png', { onclick: js, style: 'cursor: pointer;', title: title, alt: 'Create'})
213
+ else
214
+ image_tag('drg_cms/add.png', { onclick: js, style: 'cursor: pointer;', title: title, alt: 'Create'})
215
+ end
216
+ html.html_safe
217
+ end
218
+
219
+ ####################################################################
220
+ #
221
+ ####################################################################
222
+ def dc_link_for_edit(opts)
223
+ title = opts.delete(:title) #
224
+ target = opts.delete(:target) || 'iframe_cms'
225
+ opts[:action] = 'edit'
226
+ opts[:controller] ||= 'cmsedit'
227
+ url = @parent ? @parent.url_for(opts) : url_for(opts)
228
+ js = "$('##{target}').attr('src', '#{url}'); return false;"
229
+ html = if @parent
230
+ @parent.image_tag('drg_cms/edit.png', { onclick: js, style: 'cursor: pointer;', title: title, alt: 'Edit'})
231
+ else
232
+ image_tag('drg_cms/edit.png', { onclick: js, style: 'cursor: pointer;', title: title, alt: 'Edit'})
233
+ end
234
+ html.html_safe
235
+ end
236
+
237
+ ####################################################################
238
+ # Create edit link for drg_cms
239
+ ####################################################################
240
+ def dc_link_menu_tag(title)
241
+ html =<<EOT
242
+ <dl>
243
+ <dt><div class='drgcms_popmenu' href="#"><span><img style="cursor:pointer;" src="/assets/drg_cms/edit.png" title="#{title}"></span></div></dt>
244
+ <dd>
245
+ <ul class=' div-hidden drgcms_popmenu_class'>
246
+ EOT
247
+ yield html
248
+ html << "</ul></dd></dl>"
249
+ end
250
+
251
+ ####################################################################
252
+ # Create one option in page edit link
253
+ ####################################################################
254
+ def dc_link_for_edit1(opts, link_text) #NODOC
255
+ url = @parent.url_for(opts)
256
+ "<li><div class='drgcms_popmenu_item' style='cursor: pointer;' data-url='#{url}'>#{link_text}</div></li>\n"
257
+ end
258
+
259
+ ########################################################################
260
+ # Create edit menu for dc_page document.
261
+ ########################################################################
262
+ def dc_page_edit_menu()
263
+ return '' if @opts[:edit_mode] < 2
264
+ # save some data to cookie. This can not go to session.
265
+ t = @parent.site.page_table
266
+ kukis = { "#{t}.dc_design_id" => @page.dc_design_id,
267
+ "#{t}.menu_id" => @page.menu_id,
268
+ "#{t}.kats" => @page.kats,
269
+ "#{t}.page_id" => @page.id,
270
+ "#{t}.dc_site_id" => @parent.site.id
271
+ }
272
+ @parent.cookies[:record] = Marshal.dump(kukis)
273
+ title = "#{t('drgcms.edit')}: #{@page.subject}"
274
+ dc_link_menu_tag(title) do |html|
275
+ @opts[:editparams].merge!( :controller => 'cmsedit', :action => 'edit' )
276
+ @opts[:editparams].merge!( :id => @page.id, :table => @parent.site.page_table, formname: nil, edit_only: 'body' )
277
+ html << dc_link_for_edit1( @opts[:editparams], t('drgcms.edit_content') )
278
+
279
+ @opts[:editparams][:edit_only] = nil
280
+ html << dc_link_for_edit1( @opts[:editparams], t('drgcms.edit_advanced') )
281
+
282
+ @opts[:editparams][:action] = 'new'
283
+ html << dc_link_for_edit1( @opts[:editparams], t('drgcms.edit_new_page') )
284
+
285
+ @opts[:editparams].merge!(ids: @page.id, formname: 'dc_part', table: "#{@parent.site.page_table};dc_part" )
286
+ html << dc_link_for_edit1( @opts[:editparams], t('drgcms.edit_new_part') )
287
+ end
288
+ end
289
+
290
+ ########################################################################
291
+ # Return page class (from site record) which defines page_class table (collection)
292
+ # used for saving page data.
293
+ #
294
+ # Mostly used by forms, when some method must be called from page model.
295
+ #
296
+ # @example usage from form description:
297
+ # 30:
298
+ # name: link
299
+ # type: text_with_select
300
+ # eval: 'DcPageClass.all_pages_for_site(@parent.dc_get_site)'
301
+ ########################################################################
302
+ def dc_page_class()
303
+ dc_get_site.page_class.classify.constantize
304
+ end
305
+
306
+ ####################################################################
307
+ # Wrapper for i18 t method, with some spice added
308
+ ####################################################################
309
+ def t(key, default='')
310
+ c = I18n.t(key)
311
+ if c.class == Hash or c.match( 'translation missing' )
312
+ c = I18n.t(key, locale: 'en')
313
+ # Still not found. Return default if set
314
+ c = default unless default.blank?
315
+ end
316
+ c
317
+ end
318
+
319
+ ####################################################################
320
+ # Returns translated tablename.
321
+ ####################################################################
322
+ def t_tablename(tablename, default=nil)
323
+ t('helpers.label.' + tablename + '.tabletitle', default || tablename)
324
+ end
325
+
326
+ ############################################################################
327
+ # Translation for field name label.
328
+ ############################################################################
329
+ def t_name(name, default='')
330
+ c = t("helpers.label.#{@form['table']}.#{name}", default)
331
+ c = name.capitalize.gsub('_',' ') if c.match( 'translation missing' )
332
+ c
333
+ end
334
+
335
+ ############################################################################
336
+ # Return name (description) for specified field in document
337
+ #
338
+ # @example usage from program
339
+ # dc_name4_value('dc_user', 'name', text.id)
340
+ #
341
+ # @example usage from form description
342
+ # columns:
343
+ # 2:
344
+ # name: site_id
345
+ # eval: dc_name4_value('site','name',@record['site_id'])
346
+ #
347
+ # @param [ model ] table (collection) model name.
348
+ # @param [ field ] field name to return
349
+ # @param [ id ] id to search for
350
+ #
351
+ ############################################################################
352
+ def dc_name4_value(model, field, value)
353
+ return '' if value.nil?
354
+ c = t('helpers.label.' + model + '.choices4_' + field )
355
+ a = c.chomp.split(',').inject([]) {|r,v| r << v.split(':') }
356
+ a.each {|e| return e.first if e.last.to_s == value.to_s }
357
+ ''
358
+ end
359
+
360
+ ############################################################################
361
+ # Return name (description) for specified table and id
362
+ #
363
+ # @example usage from program
364
+ # dc_name4_id('dc_user', 'name', text.id)
365
+ #
366
+ # @example usage from form description
367
+ # columns:
368
+ # 2:
369
+ # name: site_id
370
+ # eval: name4_id('site','name',@record['site_id'])
371
+ #
372
+ # @param [ model ] table (collection) model name.
373
+ # @param [ field ] field name to return
374
+ # @param [ id ] id to search for
375
+ #
376
+ ############################################################################
377
+ def dc_name4_id(model, field, id)
378
+ return '' if id.nil?
379
+ model = model.classify.constantize if model.class == String
380
+ rec = model.find_by(id: id)
381
+ rec.nil? ? '' : rec[field]
382
+ end
383
+
384
+ ############################################################################
385
+ # Return icon representation for boolean value. Icon is a picture of checked or unchecked box.
386
+ #
387
+ # @example usage from program
388
+ # dc_icon4_boolean(some_value)
389
+ #
390
+ # @example usage from form description
391
+ # columns:
392
+ # 10:
393
+ # name: active
394
+ # eval: dc_icon4_boolean
395
+ #
396
+ # @param [ value ] value
397
+ ############################################################################
398
+ def dc_icon4_boolean(val)
399
+ dc_dont?(val) ? image_tag('drg_cms/checkbox-unchecked.png') : image_tag('drg_cms/checkbox-checked.png')
400
+ end
401
+
402
+ ############################################################################
403
+ # Safely output date/time value in desired format. Will return '' if value is nil.
404
+ #
405
+ # Mostly used for calling from views.
406
+ ############################################################################
407
+ def dc_date_time(val, default=nil)
408
+ return '' if val.nil?
409
+ default = ( val.class == Date ? t('date.formats.default') : t('time.formats.default') ) if default.nil?
410
+ val.strftime(default)
411
+ end
412
+
413
+ ####################################################################
414
+ # Determine and return site record from url. Site record will be cached in
415
+ # @site variable.
416
+ ####################################################################
417
+ def dc_get_site()
418
+ return @site if @site # already cached
419
+ #
420
+ req = @parent ? @parent.request.url : request.url # different when called from renderer
421
+ uri = URI.parse(req)
422
+ @site = DcSite.find_by(name: uri.host)
423
+ # Site can be aliased
424
+ if @site and !@site.alias_for.blank?
425
+ @site = DcSite.find_by(name: @site.alias_for)
426
+ end
427
+ # Development environment. Check if site with name test exists and use
428
+ # homepagelink field as pointer to real site name.
429
+ if @site.nil? and ENV["RAILS_ENV"] != 'production'
430
+ @site = DcSite.find_by(name: 'test')
431
+ @site = DcSite.find_by(name: @site.alias_for) if @site
432
+ end
433
+ @site = nil if @site and !@site.active # site is disabled
434
+ @site
435
+ end
436
+
437
+ ############################################################################
438
+ # Return array of policies defined in a site document formated to be used
439
+ # as choices select field, where policy_id field is defined in document.
440
+ #
441
+ # @example (as used in forms)
442
+ # name: policy_id
443
+ # type: select
444
+ # eval: dc_choices4_site_policies
445
+ # html:
446
+ # include_blank: true
447
+ ############################################################################
448
+ def dc_choices4_site_policies()
449
+ site = dc_get_site()
450
+ site.dc_policies.all.inject([]) { |r, policy| r << [ policy.name, policy.id] if policy.active }
451
+ end
452
+
453
+ ############################################################################
454
+ # Returns list of table names (collections) as array of choices for use in select field
455
+ # on data permission form. Method gets list of available collections from
456
+ # cms_menu.yml menu definition file.
457
+ #
458
+ # @example (as used in forms)
459
+ # eval: dc_choices4_tables_list
460
+ ############################################################################
461
+ def dc_choices4_tables_list
462
+ menus = []
463
+ DrgCms.paths(:forms).reverse.each do |path|
464
+ f = "#{path}/cms_menu.yml"
465
+ menus << YAML.load_file(f)['menu'] if File.exist?(f)
466
+ end
467
+ #
468
+ choices = [] #['Default permission','Default permission']]
469
+ menus.each do |section|
470
+ section['items'].each do |e|
471
+ c = t(e['caption'], e['caption'])
472
+ choices << ["#{c} - #{e['params']['table']}", e['params']['table']]
473
+ end
474
+ end
475
+ choices
476
+ end
477
+
478
+ ##########################################################################
479
+ # Returns available choices used by collection edit select field on CMS top menu.
480
+ #
481
+ # @example: dc_choices4_cmsmenu
482
+ #
483
+ # Returns 2d array ready for use in select field.
484
+ ##########################################################################
485
+ def dc_choices4_cmsmenu()
486
+ menus = []
487
+ DrgCms.paths(:forms).reverse.each do |path|
488
+ f = "#{path}/cms_menu.yml"
489
+ menus << YAML.load_file(f)['menu'] if File.exist?(f)
490
+ end
491
+ #
492
+ choices = []
493
+ menus.each do |v|
494
+ choices << ["--- #{ t(v['section'], v['section']) }",'#']
495
+ v['items'].each do |i|
496
+ opts = { controller: i['controller'], action: i['action'] }
497
+ i['params'].each {|k,v| opts.merge!(k => v) }
498
+ choices << [ t(i['caption'],i['caption']), url_for( opts ) ]
499
+ end
500
+ end
501
+ choices
502
+ end
503
+
504
+ ############################################################################
505
+ # Returns list of directories as array of choices for use in select field
506
+ # on folder permission form.
507
+ #
508
+ # @example (as used in forms)
509
+ # eval: dc_choices4_folders_list
510
+ ############################################################################
511
+ def dc_choices4_folders_list
512
+ public = File.join(Rails.root,'public')
513
+ home = File.join(public,dc_get_site.files_directory)
514
+ choices = Dir.glob(home + '/**/*/').select { |fn| File.directory?(fn) }
515
+ choices << home # add home
516
+ choices.collect! {|e| e.gsub(public,'')} # remove public part
517
+ choices.sort
518
+ end
519
+
520
+ ############################################################################
521
+ # Returns choices for select input filed.
522
+ #
523
+ # @example
524
+ # dc_choices4('dc_mail_list', 'name', '_id', :site_only => true)
525
+ #
526
+ # @param [ model ] table (collection) model name.
527
+ # @param [ name ] field name with description
528
+ # @param [ id ] field name with id field. Default value is '_id'
529
+ #
530
+ ############################################################################
531
+ def dc_choices4(model, name, id='_id', options = {})
532
+ qry = model.classify.constantize.only(id, name).sort(name => 1)
533
+ qry = qry.where(dc_site_id: dc_get_site()) if options[:site_only]
534
+ r = []
535
+ qry.each {|v| r << [ v[name], v[id] ] }
536
+ r
537
+ end
538
+
539
+ ############################################################################
540
+ # Adds new key to record cookie, thus preparing some initial values for creating
541
+ # new record on the next call.
542
+ #
543
+ # @example
544
+ # dc_add2_record_cookie(hash)
545
+ #
546
+ # @param [ hash ] hash of cookies to add
547
+ ############################################################################
548
+ def dc_add2_record_cookie(hash)
549
+ kukis = if @parent.cookies[:record] and @parent.cookies[:record].size > 0
550
+ Marshal.load(@parent.cookies[:record])
551
+ else
552
+ {}
553
+ end
554
+ hash.each {|k,v| kukis[k] = v }
555
+ @parent.cookies[:record] = Marshal.dump(kukis)
556
+ end
557
+
558
+ ############################################################################
559
+ # Returns true if access_policy allows user to view cms part
560
+ # Returns false and message if access is not allowed
561
+ #
562
+ # @example
563
+ # dc_user_can_view(@parent, @page)
564
+ # dc_user_can_view(@parent, @page.policy_id)
565
+ #
566
+ # @param [ ctrl ] Controller object or object which holds methods to access session.
567
+ # @param [ policy_id ] Policy id to check. If record is send as parameter, method will
568
+ # check for policy_id field and use that field.
569
+ ############################################################################
570
+ def dc_user_can_view(ctrl, policy_id)
571
+ policy_id = policy_id.policy_id if policy_id and policy_id.respond_to?(:policy_id)
572
+ # Eventualy object without policy_id will be checked. This is to prevent error
573
+ policy_id = nil unless policy_id.class == BSON::ObjectId
574
+ #
575
+ site = ctrl.site
576
+ policies = site.dc_policies
577
+ # permission defined by default policy
578
+ default_policy = policies.find_by(is_default: true)
579
+ return false, 'Default accsess policy not found for the site!' unless default_policy
580
+ h = {}
581
+ default_policy.dc_policy_rules.to_a.each { |v| h[v.dc_policy_role_id] = v.permission }
582
+ # update permissions with defined policy
583
+ part_policy = nil
584
+ if policy_id
585
+ part_policy = policies.find(policy_id)
586
+ return false, 'Access policy not found for part!' unless part_policy
587
+ part_policy.dc_policy_rules.to_a.each { |v| h[v.dc_policy_role_id] = v.permission }
588
+ end
589
+ # p h
590
+ # apply guest role if user has no roles defined
591
+ if ctrl.session[:user_roles].nil?
592
+ role = DcPolicyRole.find_by(system_name: 'guest', active: true)
593
+ return false, 'System guest role not defined!' unless role
594
+ ctrl.session[:user_roles] = [role.id]
595
+ end
596
+ # Check if user has any role that allows him to view part
597
+ can_view, msg = false,''
598
+ ctrl.session[:user_roles].each do |role|
599
+ next unless h[role] # role not yet defined. Will die in next line.
600
+ if h[role] > 0
601
+ can_view = true
602
+ break
603
+ end
604
+ end
605
+ msg = if !can_view
606
+ part_policy ? t(part_policy.message,part_policy.message) : t(default_policy.message,default_policy.message)
607
+ end
608
+ return can_view, msg
609
+ end
610
+
611
+ ####################################################################
612
+ # Return true if user has required role.
613
+ # @example
614
+ # dc_user_has_role('decision_maker', session[:user_id), session[:user_roles]) => true
615
+ #
616
+ # @param [ role ] Role. Can be passed as string or role object.
617
+ # @param [ user ] User id. If not passed session[:user_id] will be used.
618
+ # @param [ roles ] Array of roles that will be searched. If not passed session[:user_roles] will be used.
619
+ ####################################################################
620
+ def dc_user_has_role( role, user=nil, roles=nil )
621
+ if roles.nil?
622
+ roles = (@parent ? @parent.session : session)[:user_roles]
623
+ end
624
+ if user.nil?
625
+ user = (@parent ? @parent.session : session)[:user_id]
626
+ end
627
+ return false if user.nil?
628
+ #
629
+ if role.class == String
630
+ rol = role
631
+ role = DcPolicyRole.find_by(name: rol)
632
+ role = DcPolicyRole.find_by(system_name: rol) if role.nil?
633
+ end
634
+ return false if role.nil?
635
+ # role is included in roles array
636
+ roles.include?(role._id)
637
+ end
638
+
639
+ ####################################################################
640
+ # Returns true if parameter has value of 0, false, no or -. Returns default
641
+ # if parameter has nil value.
642
+ #
643
+ # @example
644
+ # dc_dont?('no') => true
645
+ # dc_dont?(1) => false
646
+ #
647
+ # @param [ string ] String to be examined
648
+ # @param [ default ] Default value when not set. false by default.
649
+ ####################################################################
650
+ def dc_dont?(what, default=false)
651
+ return default if what.nil?
652
+ %w(0 no - false).include?(what.to_s.downcase.strip)
653
+ end
654
+
655
+ ############################################################################
656
+ # Truncates string to the size and takes care, that words are not broken.
657
+ #
658
+ # @example
659
+ # dc_limit_string(description, 100)
660
+ #
661
+ # @param [ string ] Input string
662
+ # @param [ size ] Maximal size of the string
663
+ ############################################################################
664
+ def dc_limit_string(string, size)
665
+ return string if string.size < size
666
+ string = string[0,size]
667
+ string.chop! until (string[-1,1] == ' ' or string == '')
668
+ string << '...'
669
+ end
670
+
671
+ ############################################################################
672
+ # Returns key defined in BigTable as array of choices for use in select fields.
673
+ # It first checks if key is defined only for current site and then if site
674
+ # is not defined.
675
+ #
676
+ # @example
677
+ # eval: dc_big_table 'some-key' # as used on form
678
+ #
679
+ # @param [ string ] Key to be returned
680
+ ############################################################################
681
+ def dc_big_table(key)
682
+ ret = []
683
+ bt = DcBigTable.find_by(key: key, site: dc_get_site._id, active: true)
684
+ bt = DcBigTable.find_by(key: key, site: nil, active: true) if bt.nil?
685
+ return ret if bt.nil?
686
+ #
687
+ locale = I18n.locale.to_s
688
+ bt.dc_big_table_values.each do |v| # iterate each value
689
+ next unless v.active
690
+ desc = ''
691
+ v.dc_big_table_locales.each do |l| # iterate each locale
692
+ if l.locale == locale
693
+ desc = l.description
694
+ break
695
+ end
696
+ end
697
+ desc = v.description if desc.blank? # get description from value description
698
+ desc = v.value if desc.blank? # still blank. Use value as description
699
+ ret << [desc, v.value]
700
+ end
701
+ ret
702
+ end
703
+
704
+ end