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,54 @@
1
+ ## YAML Template for drgcms_menu1s
2
+ ---
3
+ title: User roles
4
+ table: dc_user_role
5
+
6
+ index:
7
+ actions:
8
+ 1: new
9
+
10
+ result_set:
11
+ actions:
12
+ 1: edit
13
+ 2: delete
14
+
15
+ columns:
16
+ 1:
17
+ name: dc_policy_role_id
18
+ eval: dc_name4_id,dc_policy_role,name
19
+
20
+ 3:
21
+ name: valid_from
22
+
23
+ 4:
24
+ name: valid_to
25
+
26
+ edit_title: Policy rule
27
+
28
+ form:
29
+ actions: standard
30
+
31
+ fields:
32
+
33
+ 10:
34
+ name: dc_policy_role_id
35
+ type: select
36
+ eval: DcPolicyRole.choices4_roles
37
+
38
+ 20:
39
+ name: valid_from
40
+ type: date_select
41
+ options:
42
+ include_blank: true
43
+
44
+ 30:
45
+ name: valid_to
46
+ type: date_select
47
+ options:
48
+ include_blank: true
49
+
50
+ 40:
51
+ name: active
52
+ type: check_box
53
+
54
+
@@ -0,0 +1,28 @@
1
+ ## YAML Template for drgcms_menu1s
2
+ ---
3
+ title: drgCMS First Top Menu
4
+ table: drgcms1menu
5
+ new_part:
6
+ form:
7
+ actions:
8
+ 1: cancle
9
+ 2:
10
+ type: submit
11
+ text: Create
12
+
13
+ fields:
14
+ 1:
15
+ name: part_type
16
+ type: select
17
+ choices: part,drgcms1menu
18
+ eval: Person.all.collect {|p| [ p.name, p.id ] }
19
+
20
+ 2:
21
+ name: part_embedded_in
22
+ type: select
23
+ choices: Design:design,PodjetnikPage:podjetnik_page
24
+
25
+ 3:
26
+ name: location_id
27
+ type: select
28
+ choices: site-top,ads-top,site-right,site-bottom,&get_all_locations
@@ -0,0 +1,698 @@
1
+ #--
2
+ # Copyright (c) 2012+ 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
+ module CmseditHelper
24
+ attr_reader :js
25
+
26
+ ############################################################################
27
+ #
28
+ ############################################################################
29
+ def dc_choices4_menu
30
+ m_clas = dc_get_site.menu_class
31
+ m_clas = 'DcSimpleMenu' if m_clas.blank?
32
+ klass = m_clas.classify.constantize
33
+ klass.choices4_menu(dc_get_site)
34
+ end
35
+
36
+ ########################################################################
37
+ # Since tabs it is a little more complicated to return all field names on form
38
+ ########################################################################
39
+ def dc_fields_on_form()
40
+ r = []
41
+ @form['form'].keys.each do |k|
42
+ # ignore some keywords
43
+ next if k.match('actions')
44
+ # second element of array is hash. Get only name element of hash
45
+ @form['form'][k].each {|f| r << f[1]['name'] }
46
+ end
47
+ r
48
+ end
49
+
50
+ ############################################################################
51
+ # Creates actions for list (index) dialog
52
+ ############################################################################
53
+ def dc_actions_for_index()
54
+ return '' if @form['index'].nil?
55
+ actions = @form['index']['actions']
56
+ return '' if actions.nil? or actions.size == 0
57
+ # Simulate standard actions
58
+ actions = {'standard' => true} if actions.class == String && actions == 'standard'
59
+ std_actions = {' 2' => 'new', ' 3' => 'sort', ' 4' => 'filter' }
60
+ if actions['standard']
61
+ actions.merge!(std_actions)
62
+ actions['standard'] = nil
63
+ end
64
+ # start div with hidden spinner image
65
+ html = <<EOT
66
+ <div id="dc-action-menu">
67
+ <span id="dc-spinner" class="div-hidden">#{image_tag('drg_cms/spinner.gif')}"</span>
68
+ <ul class="dc-action-menu">
69
+ EOT
70
+ #
71
+ actions.each do |k,v|
72
+ session[:form_processing] = "index:actions: #{k}=#{v}"
73
+ next if v.nil? # must be
74
+ url = @parms.clone
75
+ yaml = v.class == String ? {'type' => v} : v # if single definition simulate type parameter
76
+ action = yaml['type'].to_s.downcase
77
+ if action == 'url'
78
+ p "action: url will be deprecated. Use action: link in index: actions"
79
+ action = 'link'
80
+ end
81
+ # if return_to is present link directly to URL
82
+ if action == 'link' and yaml['url']
83
+ url = yaml['url']
84
+ else
85
+ url['controller'] = yaml['controller'] if yaml['controller']
86
+ url['action'] = yaml['action'] || action
87
+ url['table'] = yaml['table'] if yaml['table']
88
+ url['formname'] = yaml['formname'] if yaml['formname']
89
+ end
90
+ # html options of the link
91
+ yhtml = yaml['html'] || {}
92
+ yhtml['title'] = yaml['title'] if yaml['title']
93
+ html << '<li class="dc-animate">'
94
+ html << case
95
+ when action == 'sort' then # sort
96
+ choices = [['id','id']]
97
+ if @form['index']['sort']
98
+ @form['index']['sort'].split(',').each do |s|
99
+ s.strip!
100
+ choices << [ t("helpers.label.#{@form['table']}.#{s}"), s ]
101
+ end
102
+ end
103
+ t('drgcms.sort') + select('sort', 'sort', choices, { include_blank: true }, { class: 'drgcms_sort', 'data-table' => @form['table']} )
104
+
105
+ when action == 'filter' then # filter
106
+ caption = t('drgcms.filter')
107
+ s = session[@form['table']]
108
+ # add checked image to filter, so user will know that data is filtered
109
+ caption << '&nbsp;'+image_tag('drg_cms/checkbox-checked.png') if s and s[:filter]
110
+ yhtml['onclick'] = "$('#drgcms_filter').toggle(300);"
111
+ link_to(caption.html_safe, '#', yhtml )
112
+ when action == 'menu' then # menu
113
+ caption = t(v['caption'], v['caption'])
114
+ caption + eval(v['eval'])
115
+ else
116
+ caption = yaml['caption'] || yaml['text']
117
+ caption = caption ? t(caption, caption) : t('drgcms.' + action)
118
+ link_to(caption, url, yhtml)
119
+ end
120
+ html << '</li>'
121
+ end
122
+ html << '</ul></div>'
123
+ html.html_safe
124
+ end
125
+
126
+ ############################################################################
127
+ # Subroutine of dc_div_filter
128
+ ############################################################################
129
+ def _get_field_def(name) #NODOC
130
+ @form['form'].each do |tab|
131
+ next if tab.first.match('actions')
132
+ tab.each do |field|
133
+ next if field.class == String
134
+ field.each {|k,v| return v if v['name'] == name }
135
+ end
136
+ end
137
+ nil
138
+ end
139
+
140
+ ############################################################################
141
+ # Finds field definition on form and use it for filter input. Subroutine of dc_div_filter.
142
+ ############################################################################
143
+ def _get_field_div(name) #NODOC
144
+ # field not defined on form. Must be defined: name as form_field_type
145
+ if name.match(' as ')
146
+ name, dummy, type = name.split(' ')
147
+ field = {"name" => name, "type" => type, "html"=>{"size"=>20}}
148
+ else
149
+ field = _get_field_def(name)
150
+ field = {"name" => name, "type" => 'text_field', "html"=>{"size"=>20}} if field.nil?
151
+ end
152
+ klas_string = field['type'].camelize
153
+ klas = DrgcmsFormField::const_get(klas_string)
154
+ o = klas.new(self, @record, field).render
155
+ "<span id=\"filter_#{field['name']}\" class=\"div-hidden\">" << o.html << (o.js.size > 2 ? javascript_tag(o.js) : '') << '</span>'
156
+ end
157
+
158
+ ############################################################################
159
+ # Creates filter div for index/filter action.
160
+ ############################################################################
161
+ def dc_div_filter()
162
+ choices, inputs = [], ''
163
+ # searching by id is added by default
164
+ filter = (@form['index'] and @form['index']['filter']) ? @form['index']['filter'] + ',' : ''
165
+ filter << 'id as text_field'
166
+ filter.split(',').each do |f|
167
+ f.strip!
168
+ name = f.match(' as ') ? f.split(' ').first : f
169
+ choices << [ t("helpers.label.#{@form['table']}.#{name}", name), name ]
170
+ # find field definition on form and use it for input field definition
171
+ inputs << _get_field_div(f)
172
+ end
173
+ choices4_operators = t('drgcms.choices4_filter_operators').chomp.split(',').inject([]) {|r,v| r << (v.match(':') ? v.split(':') : v )}
174
+ html =<<EOT
175
+ <div id="drgcms_filter">
176
+ #{ form_tag :table => @form['table'], filter: :on, action: :index, method: :post }
177
+ #{ select(nil, 'filter_field', choices, { include_blank: true}) }
178
+ #{ select(nil, 'filter_oper', choices4_operators) }
179
+ #{ inputs }
180
+ <br>
181
+ <table class="dc-menu">
182
+ <td class="dc-link-submit dc-animate">#{submit_tag(t('drgcms.filter_on'), :class => 'dc-submit')}</td>
183
+ <td class="dc-link dc-animate">#{link_to t('drgcms.filter_off'), action: 'index', filter: 'off', :table => @form['table']}</td>
184
+ </table>
185
+ </form>
186
+ </div>
187
+
188
+ EOT
189
+ html.html_safe
190
+ end
191
+
192
+ ############################################################################
193
+ # Creates title for result
194
+ ############################################################################
195
+ def dc_table_title_for_result(result=nil)
196
+ title = if @form['title'] # form has title section
197
+ t(@form['title'],@form['title'])
198
+ else # get name from translations
199
+ t('helpers.label.' + @form['table'] + '.tabletitle', @form['table'])
200
+ end
201
+ dc_table_title(title, result)
202
+ end
203
+
204
+ ############################################################################
205
+ # Creates code for link or ajax action type
206
+ ############################################################################
207
+ def dc_link_or_ajax(yaml, parms)
208
+ method = yaml['method'] || yaml['request'] || 'get'
209
+ caption = yaml['caption'] || yaml['text']
210
+ p "Form: result_set:action:text directive will be deprecated. Use caption instead of text." if yaml['text']
211
+ #
212
+ if yaml['type'] == 'link'
213
+ if yaml['icon'] # icon
214
+ link_to( image_tag(yaml['icon'], class: 'dc-link-img dc-link-ajax dc-animate'), parms, method: method, title: t(yaml['title'],yaml['title']) )
215
+ else # caption
216
+ '<span class="dc-link-ajax dc-animate">' + link_to(" #{t(caption, caption)} ", parms, method: method, title: t(yaml['title'],yaml['title']) ) + '</span>'
217
+ end
218
+ else # ajax
219
+ url = url_for(parms)
220
+ if yaml['icon'] # icon
221
+ image_tag(yaml['icon'], class: 'dc-link-img dc-link-ajax dc-animate', 'data-url' => url, 'data-request' => method)
222
+ else # caption
223
+ %Q[<span class="dc-link-ajax dc-animate" data-url="#{url}" data-request="#{method}">#{caption}</span>]
224
+ end
225
+ end
226
+ end
227
+
228
+ ############################################################################
229
+ # Creates actions for result set row
230
+ ############################################################################
231
+ def dc_actions_for_result(record)
232
+ actions = @form['result_set']['actions']
233
+ return '' if actions.nil?
234
+ # standard actions
235
+ actions = {'standard' => true} if actions.class == String && actions == 'standard'
236
+ std_actions = {' 2' => 'edit', ' 3' => 'delete'}
237
+ actions.merge!(std_actions) if actions['standard']
238
+ #
239
+ width = @form['result_set']['actions_width'] || 22*actions.size
240
+ html = "<td style=\"width: #{width}px;\">"
241
+ actions.each do |k,v|
242
+ session[:form_processing] = "result_set:actions: #{k}=#{v}"
243
+ next if k == 'standard' # ignore standard definition
244
+ parms = @parms.clone
245
+ yaml = v.class == String ? {'type' => v} : v # if single definition simulate type parameter
246
+ html << case
247
+ when yaml['type'] == 'edit' then
248
+ parms['action'] = 'edit'
249
+ parms['id'] = record.id
250
+ link_to( image_tag('drg_cms/edit.png', class: 'dc-link-img dc-animate'), parms )
251
+ when yaml['type'] == 'duplicate' then
252
+ parms['id'] = record.id
253
+ # duplicate string will be added to these fields.
254
+ parms['dup_fields'] = yaml['dup_fields']
255
+ link_to( image_tag('drg_cms/copy.png', class: 'dc-link-img dc-animate'), parms, data: { confirm: t('drgcms.confirm_dup') }, method: :post )
256
+ when yaml['type'] == 'delete' then
257
+ parms['action'] = 'destroy'
258
+ parms['id'] = record.id
259
+ link_to( image_tag('drg_cms/x.png', class: 'dc-link-img dc-animate'), parms, data: { confirm: t('drgcms.confirm_delete') }, method: :delete )
260
+ # undocumented so far
261
+ when yaml['type'] == 'edit_embedded'
262
+ parms['controller'] = 'cmsedit'
263
+ parms['table'] += ";#{yaml['table']}"
264
+ parms['ids'] ||= ''
265
+ parms['ids'] += "#{record.id};"
266
+ link_to( image_tag('drg_cms/cols.png', class: 'dc-link-img dc-animate'), parms, method: :get )
267
+ when yaml['type'] == 'link' || yaml['type'] == 'ajax' then
268
+ if yaml['url']
269
+ parms['controller'] = yaml['url']
270
+ parms['idr'] = record.id
271
+ else
272
+ parms['id'] = record.id
273
+ end
274
+ parms['controller'] = yaml['controller'] if yaml['controller']
275
+ parms['action'] = yaml['action'] if yaml['action']
276
+ parms['table'] = yaml['table'] if yaml['table']
277
+ parms['formname'] = yaml['formname'] if yaml['formname']
278
+ parms['target'] = yaml['target'] if yaml['target']
279
+ dc_link_or_ajax(yaml, parms)
280
+ else # error.
281
+ yaml['type'].to_s
282
+ end
283
+ end
284
+ html << '</td>'
285
+ html.html_safe
286
+ end
287
+
288
+ ############################################################################
289
+ # Creates table header for result set
290
+ ############################################################################
291
+ def dc_header_for_result()
292
+ c = ''
293
+ actions = @form['result_set']['actions']
294
+ c = '<th style="border-left: 0px;">&nbsp;</th>' unless actions.nil?
295
+
296
+ if (columns = @form['result_set']['columns'])
297
+ columns.each do |k,v|
298
+ session[:form_processing] = "result_set:columns: #{k}=#{v}"
299
+ th = '<th '
300
+ v = {'name' => v} if v.class == String
301
+ caption = v['caption'] || t("helpers.label.#{@form['table']}.#{v['name']}")
302
+ th << "style=\"#{v['style']}\" " if v['style']
303
+ th << "class=\"#{v['class']}\" " if v['class']
304
+ # no sorting when embedded field or custom filter is active
305
+ if @tables.size == 1 and @form['result_set']['filter'].nil?
306
+ th << ">#{link_to(caption, sort: v['name'], table: @tables[0][1], action: :index )}</th>"
307
+ else
308
+ th << ">#{caption}</th>"
309
+ end
310
+ c << th
311
+ end
312
+ end
313
+ c.html_safe
314
+ end
315
+
316
+ ############################################################################
317
+ # Formats value acording to format supplied or data type. There is lots of things missing here.
318
+ #TODO Enable formating numbers.
319
+ ############################################################################
320
+ def dc_format_value(value, format=nil)
321
+ return '' if value.nil?
322
+ klass = value.class.to_s
323
+ if klass.match('Time')
324
+ format ||= t('time.formats.default')
325
+ value.strftime(format)
326
+ elsif klass.match('Date')
327
+ format ||= t('date.formats.default')
328
+ value.strftime(format)
329
+ else
330
+ value
331
+ end
332
+ end
333
+
334
+ ############################################################################
335
+ # Creates columns for result set
336
+ ############################################################################
337
+ def dc_columns_for_result(document)
338
+ html = ''
339
+ if (columns = @form['result_set']['columns'])
340
+ columns.each do |k,v|
341
+ session[:form_processing] = "result_set:columns: #{k}=#{v}"
342
+ # convert shortcut to hash
343
+ v = {'name' => v} if v.class == String
344
+ td = '<td '
345
+ td << "style=\"#{v['style']}\" " if v['style']
346
+ td << "class=\"#{v['class']}\" " if v['class']
347
+ # eval
348
+ value = if v['eval']
349
+ if v['eval'].match('dc_name4_id')
350
+ a = v['eval'].split(',')
351
+ dc_name4_id(a[1], a[2], document[ v['name'] ])
352
+ elsif v['eval'].match('dc_name4_value')
353
+ dc_name4_value( @form['table'], v['name'], document[ v['name'] ] )
354
+ elsif v['eval'].match('eval ')
355
+ # evaluate with specified parameters
356
+ else
357
+ if v['params']
358
+ if v['params'] == 'document' # pass document as parameter when all
359
+ eval( "#{v['eval']} document")
360
+ else # list of fields delimeted by ,
361
+ params = v['params'].chomp.split(',').inject('') do |result,e|
362
+ result << (e.match(/\.|\:|\(/) ? e : "document['#{e.strip}']") + ','
363
+ end
364
+ params.chomp!(',')
365
+ eval( "#{v['eval']} #{params}")
366
+ end
367
+ else
368
+ eval( "#{v['eval']} '#{document[ v['name'] ]}'")
369
+ end
370
+ end
371
+ else
372
+ dc_format_value(document[ v['name'] ], v['format'])
373
+ end
374
+ # td << ">#{value}</td>"
375
+ html << td << ">#{value}</td>"
376
+ end
377
+ end
378
+ html.html_safe
379
+ end
380
+
381
+ ############################################################################
382
+ #
383
+ ############################################################################
384
+ def dc_dialog_for_sort()
385
+
386
+ end
387
+
388
+ ############################################################################
389
+ # Creates actions for form
390
+ ############################################################################
391
+ def dc_actions_for_form()
392
+ # create standard actions
393
+ std_actions = {' 1' => 'back', ' 2' => {'type' => 'submit', 'caption' => 'Save'},
394
+ ' 3' => {'type' => 'submit', 'caption' => 'Save&Back'} }
395
+ # when edit only
396
+ unless @record.id.nil?
397
+ # std_actions.merge!({' 4' => 'delete', ' 6' => 'new'} ) # delete is not OK here
398
+ std_actions.merge!({' 6' => 'new'} )
399
+ std_actions.merge!(@record.active ? {' 5' => 'disable'} : {' 5' => 'enable'} ) if @record.respond_to?('active')
400
+ end
401
+ actions = @form['form']['actions']
402
+ # shortcut for actions: standard
403
+ actions = nil if actions.class == String && actions == 'standard'
404
+ # standard actions
405
+ actions = std_actions if actions.nil?
406
+ if actions['standard']
407
+ actions.merge!(std_actions)
408
+ actions['standard'] = nil
409
+ end
410
+ # Update save and save&back
411
+ actions.each do |k,v|
412
+ if v.class == String
413
+ if v.match(/save\&back/i)
414
+ actions[k] = {'type' => 'submit', 'caption' => 'Save&Back'}
415
+ elsif v == 'save'
416
+ actions[k] = {'type' => 'submit', 'caption' => 'Save'}
417
+ end
418
+ end
419
+ end
420
+ # Sort so that standard actions come first
421
+ actions = actions.to_a.sort {|x,y| x[0].to_s <=> y[0].to_s}
422
+ # Add spinner to the beginning
423
+ c = %Q[<td id="dc-spinner" class="div-hidden">#{image_tag('drg_cms/spinner.gif')}</td>]
424
+ actions.each do |element|
425
+ session[:form_processing] = "form:actions: #{element}"
426
+ v = element[1]
427
+ next if v.nil? # yes it happends
428
+ p "Using text option in actions_for form is replaced with caption. Table #{@form['table']}" if v['text']
429
+ # on_save_ok should't go inside td tags
430
+ if (element[0] == 'on_save_ok') then
431
+ c << hidden_field_tag(:on_save_ok, v)
432
+ next
433
+ end
434
+ #
435
+ parms = @parms.clone
436
+ if v.class == String
437
+ c << '<td class="dc-link dc-animate">'
438
+ c << case
439
+ when (v == 'back' or v == 'cancle') then
440
+ # If return_to is present link directly to URL
441
+ if parms['xreturn_to']
442
+ link_to(t('drgcms.back'), parms['return_to'] )
443
+ else
444
+ parms['action'] = 'index'
445
+ link_to(t('drgcms.back'), parms)
446
+ end
447
+ when v == 'delete' then
448
+ parms['operation'] = v
449
+ parms['id'] = @record.id
450
+ link_to( t('drgcms.delete'), parms, data: { confirm: t('drgcms.confirm_delete') }, method: :delete )
451
+ when v == 'new' then
452
+ parms['action'] = v
453
+ #parms['id'] = @record.id
454
+ link_to( t('drgcms.new'), parms)
455
+ when (v == 'enable' or v == 'disable') then
456
+ parms['operation'] = v
457
+ parms['id'] = @record.id
458
+ link_to( t("drgcms.#{v}"), parms, method: :delete )
459
+ else
460
+ "err1 #{element[0]}=>#{v}"
461
+ end
462
+ c << '</td>'
463
+ # non standard actions
464
+ else
465
+ c << case
466
+ # submit button
467
+ when v['type'] == 'submit'
468
+ v['caption'] ||= v['text'] || 'save'
469
+ '<td class="dc-link-submit dc-animate">' +
470
+ submit_tag(t('drgcms.' + v['caption'].downcase, v['caption']), :data => v['params'], :class => 'dc-submit') +
471
+ '</td>'
472
+ # delete with some sugar added
473
+ when v['type'] == 'delete'
474
+ parms['id'] = @record.id
475
+ parms.merge!(v['params'])
476
+ '<td class="dc-link dc-animate">' +
477
+ link_to( t('drgcms.delete'), parms, data: t('drgcms.confirm_delete'), method: :delete ) +
478
+ '</td>'
479
+ # ajax or link button
480
+ when v['type'] == 'ajax' || v['type'] == 'link'
481
+ parms = {}
482
+ # direct url
483
+ if v['url']
484
+ parms['controller'] = v['url']
485
+ parms['idr'] = @record.id
486
+ # make url
487
+ else
488
+ parms['controller'] = v['controller']
489
+ parms['action'] = v['action']
490
+ parms['table'] = v['table']
491
+ parms['formname'] = v['formname']
492
+ parms['id'] = @record.id
493
+ # additional parameters
494
+ v['params'].each { |k,v| parms[k] = v } if v['params']
495
+ end
496
+ # Error if controller param is missing
497
+ if parms['controller'].nil?
498
+ "<td>#{t('drgcms.error')}</td>"
499
+ else
500
+ v['caption'] ||= v['text'] || 'Caption missing!'
501
+ caption = t("#{v['caption'].downcase}", v['caption'])
502
+ url = url_for(parms)
503
+ request = v['request'] || v['method'] || 'get'
504
+ if v['type'] == 'ajax' # ajax button
505
+ %Q[<td class="dc-link-ajax dc-animate" id="dc-submit-ajax" data-url="#{url}" data-request="#{request}">#{caption}</td>]
506
+ else # link button
507
+ %Q[<td class="dc-link dc-animate"><a href="#{url}">#{caption}</a></td>]
508
+ end
509
+ end
510
+ # Javascript action
511
+ when v['type'] == 'script'
512
+ v['caption'] ||= v['text'] || 'Caption missing!'
513
+ caption = t("#{v['caption'].downcase}", v['caption'])
514
+ data = {'request' => 'script', 'script' => v['js']}
515
+ %Q[<td class="dc-link-ajax dc-animate">#{ link_to(caption, '#', data: data ) }</td>]
516
+ else
517
+ '<td>err2</td>'
518
+ end
519
+ end
520
+ end
521
+ c.html_safe
522
+ end
523
+
524
+ ############################################################################
525
+ # Checks if value is defined and sets default. If values are sent it also checks
526
+ # if value is found in values. If not it will report error and set value to default
527
+ ############################################################################
528
+ def dc_check_and_default(value, default, values=nil)
529
+ return default if value.nil?
530
+ # check if value is within allowed values
531
+ if values
532
+ if !values.index(value)
533
+ # parameters should be in downcas. Check downcase version.
534
+ if n = values.index(value.downcase)
535
+ return values[n]
536
+ else
537
+ logger.error("DRG Forms: Value #{value} not within values [#{values.join(',')}]. Default #{default} used!")
538
+ return default
539
+ end
540
+ end
541
+ end
542
+ value
543
+ end
544
+
545
+ ############################################################################
546
+ # Creates input field for one tab. Subroutine of dc_fields_for_form.
547
+ ############################################################################
548
+ def dc_fields_for_tab(fields) #NODOC
549
+ @js ||= ''
550
+ html = '<table class="dc-form-table">'
551
+ labels_pos = dc_check_and_default(@form['form']['labels_pos'], 'right', ['top','left','right'])
552
+ reset_cycle()
553
+ # sort fields by name
554
+ fields.to_a.sort.each do |element|
555
+ options = element.last
556
+ session[:form_processing] = "form:fields: #{element.first}=#{options}"
557
+ # ignore if edit_only singe field is required
558
+ next if params[:edit_only] and params[:edit_only] != options['name']
559
+ # hidden_fields. Ignore description text, otherwise it will be seen on screen
560
+ if options['type'] == 'hidden_field'
561
+ html << DrgcmsFormField::HiddenField.new(self, @record, options).render
562
+ next
563
+ end
564
+ # label
565
+ options['text'] ||= options['name'].capitalize.gsub('_',' ')
566
+ text = options['text'].match('helpers.') ? t(options['text']) : t_name(options['name'], options['text'])
567
+ # help text can be defined in form or in translations starting with helpers. or as helpers.help.collection.field
568
+ help = if options['help']
569
+ options['help'].match('helpers.') ? t(options['help']) : options['help']
570
+ end
571
+ help ||= t('helpers.help.' + @form['table'] + '.' + options['name'],' ')
572
+ odd_even = cycle('odd','even')
573
+ # create field object from class and call its render method
574
+ klas_string = options['type'].camelize
575
+ field_html = if DrgcmsFormField.const_defined?(klas_string) # check if field type is defined
576
+ klas = DrgcmsFormField.const_get(klas_string)
577
+ o = klas.new(self, @record, options).render
578
+ @js << o.js
579
+ o.html
580
+ else # litle error string
581
+ "Error: Code for field type #{options['type']} not defined!"
582
+ end
583
+ #
584
+ html << if labels_pos == 'top'
585
+ %Q[<tr><td class="dc-form-label dc-color-#{odd_even} dc-align-left" title="#{help}">
586
+ <div><label for="record_#{options['name']}">#{text} </label></div>
587
+ <div id="td_record_#{options['name']}" >#{field_html}</div></td></tr>]
588
+ else
589
+ %Q[<tr><td class="dc-form-label dc-color-#{odd_even} dc-align-#{labels_pos}" title="#{help}">
590
+ <label for="record_#{options['name']}">#{text} </label></td>
591
+ <td id=\"td_record_#{options['name']}\" class=\"dc-form-field dc-color-#{odd_even}\">#{field_html}</td></tr>]
592
+ end
593
+ =begin
594
+ html << "<tr><td class=\"dc-form-label-#{odd_even}\" title=\"#{help}\">"
595
+ html << "<label for=\"record_#{options['name']}\">#{text} </label>"
596
+ html << (labels_pos == 'top' ? '<br> ': '</td>')
597
+ html << (labels_pos == 'top' ? '<div ' : '<td ')
598
+ html << "id=\"td_record_#{options['name']}\" class=\"dc-form-field-#{odd_even}\">#{field_html}"
599
+ html << (labels_pos == 'top' ? '</div>': '</td>')
600
+ html << '</tr>'
601
+ =end
602
+ # html << "<td id=\"td_record_#{options['name']}\" class=\"dc-form-field-#{odd_even}\">#{field_html}</td></tr>"
603
+ end
604
+ html << '</table></table>'
605
+ end
606
+
607
+ ############################################################################
608
+ # Main method for creating data input form
609
+ ############################################################################
610
+ def dc_fields_for_form()
611
+ if @form['edit']
612
+ p "@form['edit']['title'] directive will be depricated. Use edit_title in form directive instead! #{@form['table']}"
613
+ end
614
+ html, tabs, tdata = '',[], ''
615
+ # Only fields defined
616
+ if (fields = @form['form']['fields'])
617
+ html << "<div id='data_fields' " + (@form['form']['height'] ? "style=\"height: #{@form['form']['height']}px;\">" : '>')
618
+ html << dc_fields_for_tab(fields) + '</div>'
619
+ else
620
+ # there are multiple tabs on form
621
+ first = true # first tab
622
+ @form['form']['tabs'].keys.sort.each do |tabname|
623
+ next if tabname.match('actions')
624
+ # Tricky. If field name is not on the tab skip to next tab
625
+ if params[:edit_only]
626
+ is_on_tab = false
627
+ @form['form']['tabs'][tabname].each {|k,v| is_on_tab = true if params[:edit_only] == v['name'] }
628
+ next unless is_on_tab
629
+ end
630
+ # first div is displayed all other are hidden
631
+ tdata << "<div id='data_#{tabname}'"
632
+ tdata << ' class="div-hidden"' unless first
633
+ tdata << " style=\"height: #{@form['form']['height']}px;\"" if @form['form']['height']
634
+ tdata << ">#{dc_fields_for_tab(@form['form']['tabs'][tabname])}</div>"
635
+ tabs << tabname
636
+ first = false
637
+ end
638
+ # make it all work together
639
+ html << '<ul class="dc-form-ul" >'
640
+ first = true # first tab must be selected
641
+ tabs.each do |tab|
642
+ html << "<li id='li_#{tab}' data-div='#{tab}' class='dc-form-li #{'dc-form-li-selected' if first }'>#{t_name(tab, tab)}</li>"
643
+ first = false
644
+ end
645
+ html << '</ul>'
646
+ html << tdata
647
+ end
648
+ # add last_updated_at hidden field so controller can check if record was updated in during editing
649
+ html << hidden_field(nil, :last_updated_at, :value => @record.updated_at.to_i) if @record.respond_to?(:updated_at)
650
+ html.html_safe
651
+ end
652
+
653
+ ############################################################################
654
+ # Subroutine of dc_document_statistics
655
+ ############################################################################
656
+ def _get_user_for(field_name) #NODOC
657
+ if @record[field_name]
658
+ u = DcUser.find(@record[field_name])
659
+ return u ? u.name : @record[field_name]
660
+ end
661
+ # nil
662
+ end
663
+
664
+ ############################################################################
665
+ # Display record statistics (created_by, created_at, .... on the bottom of edit form.
666
+ # + lots of more.
667
+ ############################################################################
668
+ def dc_document_statistics
669
+ return '' if @record.new_record? or dc_dont?(@form['form']['info'])
670
+ html = "<div id='dc-document-info'>#{t('drgcms.doc_info')}</div>"
671
+ html << "<div id='dc-document-info-popup' class='div-hidden'><table>"
672
+ #
673
+ u = _get_user_for('created_by')
674
+ html << "<tr><td>#{t('drgcms.created_by', 'Created by')}: </td><td><b>#{u}</td></tr>" if u
675
+ u = _get_user_for('updated_by')
676
+ html << "<tr><td>#{t('drgcms.updated_by', 'Updated by')}: </td><td><b>#{u}</td></tr>" if u
677
+ html << "<tr><td>#{t('drgcms.created_at', 'Created at')}: </td><td><b>#{dc_format_value(@record.created_at)}</td></tr>" if @record['created_at']
678
+ html << "<tr><td>#{t('drgcms.updated_at', 'Updated at')}: </td><td><b>#{dc_format_value(@record.updated_at)}</td></tr>" if @record['updated_at']
679
+ html << '</table>'
680
+ # Copy to clipboard icon
681
+ parms = params.clone
682
+ parms[:controller] = 'dc_common'
683
+ parms[:action] = 'copy_clipboard'
684
+ url = url_for(parms)
685
+ caption = image_tag('drg_cms/copy.png', title: t('drgcms.doc_copy_clipboard'))
686
+ html << %Q[<hr><img class="dc-link-img dc-link-ajax dc-animate" data-url="#{url}" data-request="get" #{caption}]
687
+
688
+ html << '</div>'
689
+ html.html_safe
690
+ end
691
+
692
+ ############################################################################
693
+ # Insert edit menu into page
694
+ ############################################################################
695
+ def dc_get_edit_stuff(body) #NODOC
696
+ end
697
+
698
+ end