drg_cms 0.4.39 → 0.4.53
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +49 -0
- data/app/assets/images/drg_cms/file_manager.png +0 -0
- data/app/assets/javascripts/drg_cms/drg_cms.js +8 -8
- data/app/assets/stylesheets/drg_cms/drg_cms.css +22 -20
- data/app/controllers/cmsedit_controller.rb +170 -114
- data/app/controllers/dc_application_controller.rb +142 -56
- data/app/controllers/dc_common_controller.rb +56 -34
- data/app/controllers/dc_main_controller.rb +1 -4
- data/app/controllers/drgcms_controls/dc_page_controls.rb +3 -0
- data/app/forms/all_options.yml +3 -0
- data/app/forms/cms_menu.yml +100 -117
- data/app/forms/dc_design.yml +1 -1
- data/app/forms/dc_ident.yml +37 -0
- data/app/forms/dc_menu_item.yml +1 -1
- data/app/forms/dc_permission.yml +1 -1
- data/app/forms/dc_site.yml +4 -0
- data/app/helpers/cmsedit_helper.rb +44 -80
- data/app/helpers/dc_ad_renderer.rb +27 -15
- data/app/helpers/dc_application_helper.rb +433 -196
- data/app/helpers/dc_big_menu_renderer.rb +40 -40
- data/app/helpers/dc_captcha_renderer.rb +38 -25
- data/app/helpers/dc_common_renderer.rb +15 -48
- data/app/helpers/dc_menu_renderer.rb +30 -20
- data/app/helpers/dc_page_renderer.rb +14 -18
- data/app/helpers/dc_part_renderer.rb +45 -16
- data/app/helpers/dc_piece_renderer.rb +23 -29
- data/app/helpers/dc_poll_renderer.rb +31 -20
- data/app/helpers/dc_renderer.rb +5 -4
- data/app/helpers/dc_simple_menu_renderer.rb +90 -68
- data/app/models/{__dc_global_data.rb → __dc_stat.rb} +20 -21
- data/app/models/dc_ad.rb +13 -1
- data/app/models/dc_ad_stat.rb +6 -0
- data/app/models/dc_big_menu.rb +15 -2
- data/app/models/dc_big_table.rb +27 -4
- data/app/models/dc_big_table_locale.rb +7 -0
- data/app/models/dc_big_table_value.rb +7 -0
- data/app/models/dc_category.rb +9 -3
- data/app/models/dc_design.rb +50 -0
- data/app/models/dc_dummy.rb +41 -1
- data/app/models/dc_folder_permission.rb +9 -2
- data/app/models/{dc_global_data.rb → dc_ident.rb} +20 -22
- data/app/models/dc_journal.rb +9 -1
- data/app/models/dc_key_value_store.rb +41 -4
- data/app/models/dc_link.rb +7 -0
- data/app/models/dc_menu.rb +20 -3
- data/app/models/dc_menu_item.rb +7 -0
- data/app/models/dc_page.rb +31 -12
- data/app/models/dc_part.rb +34 -4
- data/app/models/dc_permission.rb +32 -12
- data/app/models/dc_piece.rb +32 -4
- data/app/models/dc_policy.rb +17 -11
- data/app/models/dc_policy_role.rb +12 -7
- data/app/models/dc_policy_rule.rb +32 -4
- data/app/models/dc_poll.rb +8 -0
- data/app/models/dc_poll_item.rb +6 -0
- data/app/models/dc_simple_menu.rb +18 -3
- data/app/models/dc_simple_menu_item.rb +20 -2
- data/app/models/dc_site.rb +13 -3
- data/app/models/dc_stat.rb +8 -1
- data/app/models/dc_user.rb +18 -2
- data/app/models/dc_user_role.rb +7 -0
- data/app/models/dc_visit.rb +5 -0
- data/app/{helpers → models}/drgcms_form_field.rb +171 -73
- data/app/views/__dc_at_the_beginning/create.html.erb +9 -0
- data/app/views/__dc_at_the_beginning/index.html.erb +19 -0
- data/app/views/cmsedit/_edit_stuff.html.erb +2 -0
- data/app/views/cmsedit/_form.html.erb +0 -1
- data/app/views/dc_mail/subscribe.html.erb +0 -0
- data/config/initializers/kaminari_patch.rb +5 -4
- data/config/locales/drgcms_en.yml +4 -0
- data/config/locales/drgcms_sl.yml +1 -0
- data/config/locales/models_en.yml +14 -3
- data/config/locales/models_sl.yml +13 -4
- data/drg_cms.gemspec +4 -4
- data/lib/drg_cms.rb +37 -8
- data/lib/drg_cms/engine.rb +2 -2
- data/lib/drg_cms/version.rb +3 -2
- data/lib/tasks/at_the_beginning.yml +0 -0
- data/lib/tasks/dc_at_the_beginning.rake +118 -0
- data/lib/tasks/dc_cleanup.rake +19 -7
- data/lib/tasks/log_statistics.rb +66 -0
- data/lib/tasks/site_statistics.rake +29 -12
- data/test/dummy/app/controllers/application_controller.rb +1 -1
- data/test/dummy/app/helpers/application_helper.rb +1 -1
- metadata +15 -26
- data/README.rdoc +0 -3
- data/app/controllers/dc_at_the_beginning_controller.rb +0 -120
- data/app/controllers/dc_mail_controller.rb +0 -89
- data/app/forms/dc_forum_cat.yml +0 -54
- data/app/forms/dc_forum_forum.yml +0 -53
- data/app/forms/dc_forum_msg.yml +0 -124
- data/app/forms/dc_forum_privmsg.yml +0 -125
- data/app/forms/dc_forum_topic.yml +0 -131
- data/app/forms/dc_mail.yml +0 -88
- data/app/forms/dc_mail_address.yml +0 -56
- data/app/forms/dc_mail_list.yml +0 -44
- data/app/forms/dc_mail_list_member.yml +0 -42
- data/app/helpers/dc_mail_renderer.rb +0 -76
- data/app/models/dc_mail.rb +0 -64
- data/app/models/dc_mail_address.rb +0 -69
- data/app/models/dc_mail_list.rb +0 -48
- data/app/models/dc_mail_list_member.rb +0 -34
- data/app/models/dc_sendmail.rb +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2170ac5278d4127c49a981b33ffc4c7971ab2044
|
4
|
+
data.tar.gz: 0d227664c634c0169283c71a1cd3dde2b49a8015
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dad0892b0d68cbaeed030987a03657e4b2fee598fb42f06bf961ed02a1e5b393201167c3fd391eed286270a22b791fc9a7e7aa3ec6a4ec9f1c8da958a573e990
|
7
|
+
data.tar.gz: c6a933b22b907d199464fe1099ec205a12800a2841c80d8c92a1f76cee167ad8f2a69db4f3382b8da843f0dd69319632799398e874038143dd8fd095cbc46495
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# DrgCms
|
2
|
+
|
3
|
+
DRG CMS is cms build on strong foundations of Ruby on Rails and Mongo DB.
|
4
|
+
|
5
|
+
Project Tracking
|
6
|
+
----------------
|
7
|
+
|
8
|
+
* [DrgCms Website and Documentation](http://www.drgcms.org)
|
9
|
+
* [DrgCms Testing website](http://test.drgcms.org)
|
10
|
+
|
11
|
+
Compatibility
|
12
|
+
-------------
|
13
|
+
|
14
|
+
DRG CMS is tested against MRI 1.9.3, 2.0.0, 2.1.0.
|
15
|
+
|
16
|
+
Documentation
|
17
|
+
-------------
|
18
|
+
|
19
|
+
Please see the DRG CMS website for up-to-date documentation:
|
20
|
+
[www.drgcms.org](http://www.drgcms.org)
|
21
|
+
|
22
|
+
License
|
23
|
+
-------
|
24
|
+
|
25
|
+
Copyright (c) 2012-2015 Damjan Rems
|
26
|
+
|
27
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
28
|
+
a copy of this software and associated documentation files (the
|
29
|
+
"Software"), to deal in the Software without restriction, including
|
30
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
31
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
32
|
+
permit persons to whom the Software is furnished to do so, subject to
|
33
|
+
the following conditions:
|
34
|
+
|
35
|
+
The above copyright notice and this permission notice shall be
|
36
|
+
included in all copies or substantial portions of the Software.
|
37
|
+
|
38
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
39
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
40
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
41
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
42
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
43
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
44
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
45
|
+
|
46
|
+
Credits
|
47
|
+
-------
|
48
|
+
|
49
|
+
Damjan Rems: damjan dot rems at gmail dot com
|
Binary file
|
@@ -40,12 +40,12 @@ dumpAttributes = function(obj) {
|
|
40
40
|
};
|
41
41
|
|
42
42
|
/*******************************************************************
|
43
|
-
* Used for removing background from iframe element.
|
43
|
+
* Used for removing background from iframe element. It is of course not working.
|
44
44
|
*******************************************************************/
|
45
45
|
remove_background_from_iframe = function(obj) {
|
46
46
|
var head = obj.head;
|
47
47
|
var css = '<style type="text/css">' +
|
48
|
-
'body{background: none;} ' +
|
48
|
+
'body{background: none; background-picture:none; } ' +
|
49
49
|
'</style>';
|
50
50
|
$(head).append(css);
|
51
51
|
};
|
@@ -226,10 +226,10 @@ $(document).ready( function() {
|
|
226
226
|
// console.log(this.contentWindow.document.body.offsetHeight);
|
227
227
|
if (this.contentWindow.document.body.offsetHeight > 10) {
|
228
228
|
this.style.height = (this.contentWindow.document.body.offsetHeight + 30) + 'px';
|
229
|
-
}
|
230
|
-
remove_background_from_iframe(this.contentWindow.document);
|
231
229
|
// scroll to it
|
232
|
-
|
230
|
+
$('#iframe_edit').dc_scroll_view();
|
231
|
+
}
|
232
|
+
// remove_background_from_iframe(this.contentWindow.document);
|
233
233
|
});
|
234
234
|
|
235
235
|
/*******************************************************************
|
@@ -249,7 +249,7 @@ $(document).ready( function() {
|
|
249
249
|
}
|
250
250
|
else if (req == "post") {
|
251
251
|
data = $('form').serialize();
|
252
|
-
alert(data);
|
252
|
+
// alert(data);
|
253
253
|
}
|
254
254
|
else {
|
255
255
|
data = {};
|
@@ -412,7 +412,7 @@ element = $(this).find(':first').attr('id');
|
|
412
412
|
* Force reload of parent page if this div appears
|
413
413
|
*******************************************************************/
|
414
414
|
$('#div-reload-parent').load( function() {
|
415
|
-
alert('div-reload-parent 1');
|
415
|
+
// alert('div-reload-parent 1');
|
416
416
|
parent.location.href=parent.location.href
|
417
417
|
});
|
418
418
|
|
@@ -420,7 +420,7 @@ element = $(this).find(':first').attr('id');
|
|
420
420
|
* Force reload of parent page if this div appears
|
421
421
|
*******************************************************************/
|
422
422
|
$('#div-reload').load( function() {
|
423
|
-
alert('div-reload 1');
|
423
|
+
// alert('div-reload 1');
|
424
424
|
location.href=location.href
|
425
425
|
});
|
426
426
|
|
@@ -24,27 +24,25 @@
|
|
24
24
|
*/
|
25
25
|
|
26
26
|
body {
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
}
|
32
|
-
|
33
|
-
.text-with-select {
|
34
|
-
width: 24px;
|
27
|
+
font-family: helvetica;
|
28
|
+
font-size: 12px;
|
29
|
+
margin: 0px;
|
30
|
+
vertical-align: middle;
|
35
31
|
}
|
36
32
|
|
37
33
|
textarea, input, select {
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
34
|
+
/*font-family: helvetica;
|
35
|
+
font-size: 13px; */
|
36
|
+
padding: 4px;
|
37
|
+
border: solid 1px #888;
|
38
|
+
box-shadow: rgba(0,0,0, 0.1) 0px 0px 4px;
|
39
|
+
border-radius: 2px;
|
40
|
+
background: linear-gradient(#ffd 4%, #fff 100%);
|
41
|
+
color: #222;
|
46
42
|
}
|
47
43
|
|
44
|
+
input { padding: 6px;}
|
45
|
+
|
48
46
|
select#record_select { padding: 1px;}
|
49
47
|
|
50
48
|
hr {
|
@@ -53,7 +51,6 @@ border: none;
|
|
53
51
|
height: 2px;
|
54
52
|
}
|
55
53
|
|
56
|
-
|
57
54
|
.div {
|
58
55
|
background-color: red;
|
59
56
|
border: 0px;
|
@@ -78,6 +75,11 @@ a:link, a:active, a:visited { color: #c43; text-decoration: none; background: tr
|
|
78
75
|
a:hover { text-decoration: none; color: #000; }
|
79
76
|
a img { border: none; }
|
80
77
|
|
78
|
+
|
79
|
+
.text-with-select {
|
80
|
+
width: 24px;
|
81
|
+
}
|
82
|
+
|
81
83
|
.no-borders {
|
82
84
|
padding: 0px;
|
83
85
|
border-spacing: 0px;
|
@@ -346,14 +348,14 @@ a img { border: none; }
|
|
346
348
|
border-bottom: 1px solid #eee;
|
347
349
|
}
|
348
350
|
.dc-readonly {
|
349
|
-
margin-left:
|
351
|
+
margin-left: 2px;
|
350
352
|
margin-top: 2px;
|
351
353
|
padding: 3px;
|
352
|
-
border: solid 1px #
|
354
|
+
border: solid 1px #aaa;
|
353
355
|
border-right: solid 1px #fff;
|
354
356
|
border-bottom: 0px;
|
355
357
|
border-radius: 2px;
|
356
|
-
background: linear-gradient(#
|
358
|
+
background: linear-gradient(#eee 1%, #fff 90%);
|
357
359
|
}
|
358
360
|
|
359
361
|
.dc-color-odd {
|
@@ -22,14 +22,66 @@
|
|
22
22
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
23
|
#++
|
24
24
|
|
25
|
+
########################################################################
|
26
|
+
# This is main controller for processing actions by DRG forms. It provides
|
27
|
+
# CRUD actions for editing MongoDB documents. DRG CMS does not require controller
|
28
|
+
# to be made for every document model but centers all actions into single
|
29
|
+
# controller. Logic required to control data entry is provided within DRG
|
30
|
+
# forms which are loaded dynamically for every action.
|
31
|
+
#
|
32
|
+
# Most of data entry controls must therefore be done in document models definitions.
|
33
|
+
# And there are controls that cannot be done in document models. Like controls
|
34
|
+
# which include url parameters or accessing session variables. This is hard to be done
|
35
|
+
# in model therefore cmsedit_controls had to be invented. cmsedit_controls are
|
36
|
+
# modules with methods that are injected into cmsedit_controller and act in runtime like
|
37
|
+
# they are part of cmsedit_controller.
|
38
|
+
#
|
39
|
+
# Since Ruby and Rails provide some automagic loading of modules DRG CMS controls must be saved
|
40
|
+
# into app/controllers/drgcms_controls folder. Every model can have its own controls file.
|
41
|
+
# dc_page model's controls live in dc_page_controls.rb file. If model has embedded document
|
42
|
+
# its control's would be found in model_embedded_controls.rb. By convention module names
|
43
|
+
# are declared in camel case, so our dc_page_controls.rb declares DrgcmsControls::DcPageControls module.
|
44
|
+
#
|
45
|
+
# Controls (among other) may contain 6 fixed callback methods.
|
46
|
+
# These methods are:
|
47
|
+
# * dc_new_record
|
48
|
+
# * dc_before_edit
|
49
|
+
# * dc_before_save
|
50
|
+
# * dc_after_save
|
51
|
+
# * dc_before_delete
|
52
|
+
# * dc_after_delete
|
53
|
+
#
|
54
|
+
# Methods dc_before_edit, before_save or before_delete may also effect flow of the application. If
|
55
|
+
# method return false (not nil but FalseClass) normal flow of the program is interrupted and last operation
|
56
|
+
# is canceled.
|
57
|
+
#
|
58
|
+
# Second control methods that can be declared in DRG CMS controls are filters for
|
59
|
+
# viewing and sorting documents. It is often required that dynamic filters are
|
60
|
+
# applied to result_set documents.
|
61
|
+
#
|
62
|
+
# result_set:
|
63
|
+
# filter: current_users_documents
|
64
|
+
#
|
65
|
+
# Example implemented controls method:
|
66
|
+
#
|
67
|
+
# def current_users_documents
|
68
|
+
# if dc_user_can(DcPermission::CAN_READ)
|
69
|
+
# dc_page.where(created_by: session[:user_id])
|
70
|
+
# else
|
71
|
+
# flash[:error] = 'You can not perform this operation!'
|
72
|
+
# nil
|
73
|
+
# end
|
74
|
+
# end
|
75
|
+
#
|
76
|
+
# If filter method returns false user will be presented with flash error.
|
77
|
+
########################################################################
|
25
78
|
class CmseditController < DcApplicationController
|
26
|
-
#before_filter :check_authorization, :except => [:login]
|
27
79
|
before_action :check_authorization, :except => [:show, :login]
|
28
80
|
|
29
81
|
########################################################################
|
30
|
-
#
|
82
|
+
# Will check and set sorting options for current result set. Subroutine of index method.
|
31
83
|
########################################################################
|
32
|
-
def check_sort_options()
|
84
|
+
def check_sort_options() #:nodoc:
|
33
85
|
table_name = @tables.first[1]
|
34
86
|
old_sort = session[table_name][:sort].to_s
|
35
87
|
sort, direction = old_sort.split(' ')
|
@@ -49,9 +101,9 @@ def check_sort_options()
|
|
49
101
|
end
|
50
102
|
|
51
103
|
########################################################################
|
52
|
-
#
|
104
|
+
# Will check and set current filter options for result set. Subroutine of index method.
|
53
105
|
########################################################################
|
54
|
-
def check_filter_options()
|
106
|
+
def check_filter_options() #:nodoc:
|
55
107
|
table_name = @tables.first[1]
|
56
108
|
session[table_name] ||= {}
|
57
109
|
# process page
|
@@ -100,11 +152,18 @@ end
|
|
100
152
|
########################################################################
|
101
153
|
def index
|
102
154
|
# If result_set is not defined on form, then it will fail. :return_to should know where to go
|
103
|
-
|
104
|
-
|
155
|
+
if @form['result_set'].nil?
|
156
|
+
return process_return_to(params[:return_to] || 'reload')
|
157
|
+
end
|
158
|
+
# result set is defined by filter method in control object
|
105
159
|
if @form['result_set']['filter']
|
106
160
|
if respond_to?(@form['result_set']['filter'])
|
107
161
|
@records = send @form['result_set']['filter']
|
162
|
+
# something iz wrong. flash[] should have explanation.
|
163
|
+
return render(action: :index) if @records.class == FalseClass
|
164
|
+
# pagination
|
165
|
+
per_page = (@form['result_set']['per_page'] || 30).to_i
|
166
|
+
@records = @records.page(params[:page]).per(per_page) if per_page > 0
|
108
167
|
else
|
109
168
|
p "Error: result_set:filter: #{@form['result_set']['filter']} not found in controls!"
|
110
169
|
end
|
@@ -115,6 +174,7 @@ def index
|
|
115
174
|
else
|
116
175
|
rec = @tables.first[0].find(@ids.first) # top most document.id
|
117
176
|
1.upto(@tables.size - 2) { |i| rec = rec.send(@tables[i][1].pluralize).find(@ids[i]) } # find embedded childrens by ids
|
177
|
+
# p rec,@tables, @tables.last[1].pluralize
|
118
178
|
@records = rec.send(@tables.last[1].pluralize) # current embedded set
|
119
179
|
# sort by order if order field is present in model
|
120
180
|
if @tables.last[1].classify.constantize.respond_to?(:order)
|
@@ -130,39 +190,35 @@ def index
|
|
130
190
|
end
|
131
191
|
|
132
192
|
########################################################################
|
133
|
-
# Filter
|
193
|
+
# Filter action.
|
134
194
|
########################################################################
|
135
195
|
def filter
|
136
196
|
index
|
137
197
|
end
|
138
198
|
|
139
199
|
########################################################################
|
140
|
-
# Show is (ab)used
|
200
|
+
# Show is (ab)used for direct login and logout into cmsedit controller. Login
|
201
|
+
# and logout actions can be directly performed by calling http://site.com/cmsedit/login
|
141
202
|
########################################################################
|
142
203
|
def show
|
143
204
|
case
|
144
205
|
when params[:id].in?(%w(login logout)) then # show login menu
|
145
206
|
session[:edit_mode] = 0
|
146
|
-
# dc_collect_menu_forms
|
147
207
|
render action: 'show', layout: 'cms'
|
148
|
-
# when params[:id] == 'copy_clipboard'
|
149
|
-
# return copy_clipboard
|
150
|
-
# when params[:id] == 'paste_clipboard'
|
151
|
-
# return paste_clipboard
|
152
208
|
end
|
153
209
|
end
|
154
210
|
|
155
211
|
########################################################################
|
156
212
|
# Show is used to display menu
|
157
213
|
########################################################################
|
158
|
-
def login
|
214
|
+
def login #:nodoc:
|
159
215
|
# session[:edit_mode] = 0 if params[:id].in? %w(login logout) # show login menu
|
160
216
|
# dc_collect_menu_forms
|
161
217
|
render action: 'show', layout: 'cms'
|
162
218
|
end
|
163
219
|
|
164
220
|
########################################################################
|
165
|
-
# New action
|
221
|
+
# New action.
|
166
222
|
########################################################################
|
167
223
|
def new
|
168
224
|
if (m = callback_method('before_new') )
|
@@ -197,35 +253,55 @@ def new
|
|
197
253
|
end
|
198
254
|
|
199
255
|
########################################################################
|
200
|
-
#
|
256
|
+
# Duplicate embedded document. Since embedded documents are returned differently
|
257
|
+
# then top level document. Subroutine of duplicate_socument.
|
201
258
|
########################################################################
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
source.
|
206
|
-
next if attr_name == '_id'
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
rec.save!
|
215
|
-
end
|
216
|
-
else
|
217
|
-
# if duplicate string must be added. Usefull for unique attributes
|
259
|
+
def duplicate_embedded(source) #:nodoc:
|
260
|
+
# TODO Works for two embedded levels. Dies with third and more levels.
|
261
|
+
dest = {}
|
262
|
+
source.each do |attr_name, value|
|
263
|
+
next if attr_name == '_id' # don't duplicate _id
|
264
|
+
if value.class == Array
|
265
|
+
dest[attr_name] = []
|
266
|
+
value.each do |ar|
|
267
|
+
dest[attr_name] << duplicate_embedded(ar)
|
268
|
+
end
|
269
|
+
else
|
270
|
+
# if duplicate string must be added. Useful for unique attributes
|
218
271
|
add_duplicate = params['dup_fields'].to_s.match(attr_name + ',')
|
219
|
-
|
220
|
-
dest
|
272
|
+
dest[attr_name] = value
|
273
|
+
dest[attr_name] << ' dup' if add_duplicate
|
221
274
|
end
|
222
275
|
end
|
223
|
-
dest
|
276
|
+
dest
|
224
277
|
end
|
225
|
-
=end
|
226
278
|
|
227
279
|
########################################################################
|
228
|
-
#
|
280
|
+
# Will create duplicate document of source document. This method is used for
|
281
|
+
# duplicating document and is called from create action.
|
282
|
+
########################################################################
|
283
|
+
def duplicate_document(source)
|
284
|
+
dest = {}
|
285
|
+
source.attribute_names.each do |attr_name|
|
286
|
+
next if attr_name == '_id' # don't duplicate _id
|
287
|
+
# if duplicate string must be added. Useful for unique attributes
|
288
|
+
add_duplicate = params['dup_fields'].to_s.match(attr_name + ',')
|
289
|
+
dest[attr_name] = source[attr_name]
|
290
|
+
dest[attr_name] << ' dup' if add_duplicate
|
291
|
+
end
|
292
|
+
#
|
293
|
+
source.embedded_relations.keys.each do |embedded_name|
|
294
|
+
next if source[embedded_name].nil? # it happens
|
295
|
+
dest[embedded_name] = []
|
296
|
+
source[embedded_name].each do |ar|
|
297
|
+
dest[embedded_name] << duplicate_embedded(ar)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
dest
|
301
|
+
end
|
302
|
+
|
303
|
+
########################################################################
|
304
|
+
# Create (or duplicate) action. Action is also used for turning filter on.
|
229
305
|
########################################################################
|
230
306
|
def create
|
231
307
|
# abusing create for turning filter on
|
@@ -250,16 +326,12 @@ def create
|
|
250
326
|
end
|
251
327
|
else # duplicate record
|
252
328
|
find_record
|
253
|
-
#
|
254
|
-
|
255
|
-
|
256
|
-
|
329
|
+
params['dup_fields'] += ',' if params['dup_fields'] # for easier field matching
|
330
|
+
new_doc = duplicate_document(@record)
|
331
|
+
create_new_empty_record(new_doc)
|
332
|
+
update_standards()
|
333
|
+
@record.save!
|
257
334
|
|
258
|
-
params['dup_fields'].to_s.split(',').each do |df|
|
259
|
-
dup[df] = dup[df] + ' duplicate' if dup.respond_to?(df) # avoid errors
|
260
|
-
end
|
261
|
-
update_standards(dup)
|
262
|
-
dup.save!
|
263
335
|
index
|
264
336
|
end
|
265
337
|
end
|
@@ -277,22 +349,19 @@ def edit
|
|
277
349
|
@parms['action'] = 'update'
|
278
350
|
end
|
279
351
|
|
280
|
-
=begin
|
281
|
-
########################################################################
|
282
|
-
# TODO Think of better way for loginng and displaying menu
|
283
|
-
# Show action.
|
284
|
-
########################################################################
|
285
|
-
def show
|
286
|
-
find_record
|
287
|
-
# @parms['action'] = 'show'
|
288
|
-
end
|
289
|
-
=end
|
290
|
-
|
291
352
|
########################################################################
|
292
353
|
# Update action.
|
293
354
|
########################################################################
|
294
355
|
def update
|
295
356
|
find_record
|
357
|
+
# check if record was not updated in mean time
|
358
|
+
if @record.respond_to?(:updated_at)
|
359
|
+
if params[:last_updated_at].to_i != @record.updated_at.to_i
|
360
|
+
flash[:error] = t('drgcms.updated_by_other')
|
361
|
+
return render(action: :edit)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
#
|
296
365
|
if dc_user_can(DcPermission::CAN_EDIT_ALL) or
|
297
366
|
( @record.respond_to?('created_by') and
|
298
367
|
@record.created_by == session[:user_id] and
|
@@ -311,7 +380,7 @@ def update
|
|
311
380
|
end
|
312
381
|
|
313
382
|
########################################################################
|
314
|
-
# Destroy
|
383
|
+
# Destroy action. Used also for enabling and disabling record.
|
315
384
|
########################################################################
|
316
385
|
def destroy
|
317
386
|
find_record
|
@@ -381,6 +450,7 @@ end
|
|
381
450
|
|
382
451
|
protected
|
383
452
|
|
453
|
+
=begin
|
384
454
|
########################################################################
|
385
455
|
# Processes on_save_ok form directive. Data is saved to session for
|
386
456
|
# safety reasons.
|
@@ -390,11 +460,13 @@ def process_on_save_ok
|
|
390
460
|
session[:on_save_ok_commit] = params[:commit]
|
391
461
|
eval(params[:on_save_ok])
|
392
462
|
end
|
463
|
+
=end
|
393
464
|
|
394
465
|
########################################################################
|
395
|
-
# Merges two forms
|
466
|
+
# Merges two forms when current form extends other form. Subroutine of read_yaml.
|
467
|
+
# With a little help of https://www.ruby-forum.com/topic/142809
|
396
468
|
########################################################################
|
397
|
-
def forms_merge(hash1, hash2)
|
469
|
+
def forms_merge(hash1, hash2)
|
398
470
|
target = hash1.dup
|
399
471
|
hash2.keys.each do |key|
|
400
472
|
if hash2[key].is_a? Hash and hash1[key].is_a? Hash
|
@@ -408,7 +480,7 @@ def forms_merge(hash1, hash2)
|
|
408
480
|
end
|
409
481
|
|
410
482
|
########################################################################
|
411
|
-
# Read
|
483
|
+
# Read drgcms form into yaml object. Subroutine of check_authorization.
|
412
484
|
########################################################################
|
413
485
|
def read_yaml
|
414
486
|
table_name = decamelize_type(params[:table].strip)
|
@@ -424,8 +496,8 @@ def read_yaml
|
|
424
496
|
form = YAML.load_file( dc_find_form_file(@form['extend']) )
|
425
497
|
@form = forms_merge(form, @form)
|
426
498
|
end
|
427
|
-
# add readonly key to form if readonly parameter is passed
|
428
|
-
@form['readonly'] = 1 if
|
499
|
+
# add readonly key to form if readonly parameter is passed in url
|
500
|
+
@form['readonly'] = 1 if params['readonly'] and %w(1 yes true).include?(params['readonly'].to_s.downcase.strip)
|
429
501
|
# p '2',@form
|
430
502
|
# !!!!!! Always use strings for key names since @parms['table'] != @parms[:table]
|
431
503
|
@parms = { 'table' => table_name, 'ids' => ids, 'formname' => formname,
|
@@ -433,10 +505,11 @@ def read_yaml
|
|
433
505
|
end
|
434
506
|
|
435
507
|
############################################################################
|
436
|
-
# Check if user is authorized for the action.
|
437
|
-
#
|
508
|
+
# Check if user is authorized for the action. If authorization is in order it will also
|
509
|
+
# load DRG form.
|
438
510
|
############################################################################
|
439
511
|
def check_authorization
|
512
|
+
params[:table] ||= params[:formname]
|
440
513
|
# Extend class with methods defined in drgcms_controls module. May include embedded forms therefor ; => _
|
441
514
|
controls_string = params[:table].gsub(';','_') + '_control'
|
442
515
|
controls = ("DrgcmsControls::#{controls_string.classify}".constantize rescue nil)
|
@@ -459,9 +532,9 @@ def check_authorization
|
|
459
532
|
end
|
460
533
|
|
461
534
|
########################################################################
|
462
|
-
# Find record for edit, update or delete.
|
535
|
+
# Find current record (document) for edit, update or delete.
|
463
536
|
########################################################################
|
464
|
-
def find_record
|
537
|
+
def find_record #:nodoc:
|
465
538
|
if @tables.size == 1
|
466
539
|
@record = @tables.first[0].find(params[:id])
|
467
540
|
else
|
@@ -474,33 +547,18 @@ end
|
|
474
547
|
########################################################################
|
475
548
|
# Creates new empty record for new and create action.
|
476
549
|
########################################################################
|
477
|
-
def create_new_empty_record
|
550
|
+
def create_new_empty_record(initial_data=nil) #:nodoc:
|
478
551
|
if @tables.size == 1
|
479
|
-
@record = @tables.first[0].new
|
552
|
+
@record = @tables.first[0].new(initial_data)
|
480
553
|
else
|
481
554
|
rec = @tables.first[0].find(@ids.first) # top most record
|
482
555
|
1.upto(@tables.size - 2) { |i| rec = rec.send(@tables[i][1].pluralize).find(@ids[i]) } # find embedded childrens by ids
|
483
|
-
@record = rec.send(@tables.last[1].pluralize).new # new record
|
556
|
+
@record = rec.send(@tables.last[1].pluralize).new(initial_data) # new record
|
484
557
|
end
|
485
558
|
end
|
486
|
-
|
487
|
-
########################################################################
|
488
|
-
# Get data for multitext_autocomplete field. That is field which is saved as record[kats_****]
|
489
|
-
#
|
490
|
-
# @param [ name ] Name of field
|
491
|
-
########################################################################
|
492
|
-
def get_data_multitext_autocomplete(name)
|
493
|
-
r = []
|
494
|
-
params['record'].each do |k,v|
|
495
|
-
# if it starts with - then it was removed
|
496
|
-
r << BSON::ObjectId(v) if k.match("#{name}_") and v[0,1] != '-'
|
497
|
-
end
|
498
|
-
r.uniq!
|
499
|
-
r
|
500
|
-
end
|
501
|
-
=end
|
559
|
+
|
502
560
|
########################################################################
|
503
|
-
#
|
561
|
+
# Update standard fields like updated_by, created_by, site_id
|
504
562
|
########################################################################
|
505
563
|
def update_standards(record = @record)
|
506
564
|
record.updated_by = session[:user_id] if record.respond_to?('updated_by')
|
@@ -514,9 +572,9 @@ end
|
|
514
572
|
|
515
573
|
########################################################################
|
516
574
|
# Since tabs have been introduced on form it is a little more complicated
|
517
|
-
# to get all
|
575
|
+
# to get all edit fields on form. This method does it. Subroutine of save_data.
|
518
576
|
########################################################################
|
519
|
-
def fields_on_form()
|
577
|
+
def fields_on_form() #:nodoc:
|
520
578
|
fields = []
|
521
579
|
if @form['form']['fields']
|
522
580
|
# second element of array is hash. Get only hash element
|
@@ -530,14 +588,11 @@ def fields_on_form()
|
|
530
588
|
end
|
531
589
|
|
532
590
|
########################################################################
|
533
|
-
# Save changes to journal table. Saves all parameters to
|
534
|
-
#
|
535
|
-
#
|
536
|
-
#
|
537
|
-
#
|
538
|
-
# save_journal(true)
|
539
|
-
#
|
540
|
-
# @param [ changes ] Changes for the record
|
591
|
+
# Save document changes to journal table. Saves all parameters to retrieve record if needed.
|
592
|
+
#
|
593
|
+
# [Parameters:]
|
594
|
+
# [operation] 'delete' or 'update'.
|
595
|
+
# [changes] Current document changed fields.
|
541
596
|
########################################################################
|
542
597
|
def save_journal(operation, changes = {})
|
543
598
|
# return unless session[:save_journal]
|
@@ -564,10 +619,10 @@ def save_journal(operation, changes = {})
|
|
564
619
|
end
|
565
620
|
|
566
621
|
########################################################################
|
567
|
-
# Determines if callback method is defined in parameters or in
|
622
|
+
# Determines if callback method is defined in parameters or in control module.
|
568
623
|
# Returns callback method name or nil if not defined.
|
569
624
|
########################################################################
|
570
|
-
def callback_method(key)
|
625
|
+
def callback_method(key) #:nodoc:
|
571
626
|
data_key = key.gsub('_','-') # data fields translate _ to -
|
572
627
|
cb = case
|
573
628
|
when params['data'] && params['data'][data_key] then params['data'][data_key]
|
@@ -576,7 +631,6 @@ def callback_method(key)
|
|
576
631
|
when params[key] then params[key]
|
577
632
|
else nil
|
578
633
|
end
|
579
|
-
# p [ '***********************',key, cb, params['data'],params['key']]
|
580
634
|
#
|
581
635
|
ret = case
|
582
636
|
when cb.nil? then cb # otherwise there will be errors in next lines
|
@@ -592,19 +646,22 @@ end
|
|
592
646
|
########################################################################
|
593
647
|
# Calls callback method.
|
594
648
|
########################################################################
|
595
|
-
def call_callback_method(m)
|
649
|
+
def call_callback_method(m) #:nodoc:
|
596
650
|
send(m) if respond_to?(m)
|
597
651
|
end
|
598
652
|
|
599
653
|
########################################################################
|
600
|
-
# Same as javascript_tag helper
|
654
|
+
# Same as javascript_tag helper. Ajax form actions may results in javascript code to be returned.
|
655
|
+
# This will add javascript tag to code.
|
601
656
|
########################################################################
|
602
|
-
def js_tag(script)
|
657
|
+
def js_tag(script) #:nodoc:
|
603
658
|
"<script type=\"text/javascript\">#{script}</script>"
|
604
659
|
end
|
605
660
|
|
606
661
|
########################################################################
|
607
|
-
# Process return_to parameter when
|
662
|
+
# Process return_to parameter when defined on form or set by controls methods.
|
663
|
+
# params['return_to'] may contain 'index', 'reload' or 'parent.reload' or any valid url to
|
664
|
+
# return to, after successful controls method call.
|
608
665
|
########################################################################
|
609
666
|
def process_return_to(return_to)
|
610
667
|
script = case
|
@@ -617,37 +674,34 @@ def process_return_to(return_to)
|
|
617
674
|
end
|
618
675
|
|
619
676
|
########################################################################
|
620
|
-
#
|
677
|
+
# Save edited data. Take care that only fields defined on form are affected.
|
678
|
+
# It also saves journal data and calls before_save and after_save callbacks.
|
621
679
|
########################################################################
|
622
680
|
def save_data
|
623
681
|
fields = fields_on_form()
|
624
|
-
p fields
|
625
682
|
return true unless fields.size > 0
|
626
683
|
#
|
627
684
|
fields.each do |v|
|
628
685
|
next if v['type'].match('embedded') # don't wipe embedded fields
|
629
686
|
next if params[:edit_only] and params[:edit_only] != v['name'] # otherwise other fields would be wiped
|
630
687
|
next unless @record.respond_to?(v['name']) # there can be temporary fields on the form
|
631
|
-
#
|
632
|
-
# TODO I used to ignore readonly fields. check if this is OK
|
633
|
-
# next if v['type'] == 'readonly' or v['readonly'] # ignore readonly fields
|
634
688
|
# return value from form field definition
|
635
689
|
value = DrgcmsFormField.const_get(v['type'].camelize).get_data(params, v['name'])
|
636
690
|
@record.send("#{v['name']}=", value)
|
637
691
|
end
|
638
|
-
#
|
639
|
-
update_standards()
|
692
|
+
#
|
640
693
|
operation = @record.new_record? ? :new : :update
|
641
|
-
# callback
|
694
|
+
# controls callback method
|
642
695
|
if (m = callback_method('before_save') )
|
643
696
|
ret = call_callback_method(m)
|
644
697
|
# dont's save if callback method returns false
|
645
698
|
return false if ret.class == FalseClass
|
646
699
|
end
|
647
|
-
#
|
700
|
+
# maybe model has dc_before_save method defined. Call it.
|
648
701
|
@record.dc_before_save(self) if @record.respond_to?('dc_before_save')
|
649
702
|
#
|
650
703
|
changes = @record.changes
|
704
|
+
update_standards() if changes.size > 0 # update only if there has been some changes
|
651
705
|
if (saved = @record.save)
|
652
706
|
save_journal(operation, changes)
|
653
707
|
# callback methods
|
@@ -658,6 +712,7 @@ def save_data
|
|
658
712
|
saved
|
659
713
|
end
|
660
714
|
|
715
|
+
=begin
|
661
716
|
########################################################################
|
662
717
|
# Returns true if model has field defined. This might be defined by mongoid,
|
663
718
|
# but I didn't found method.
|
@@ -669,5 +724,6 @@ def model_has_field?(model, field_name)
|
|
669
724
|
model.fields.each {|f| return true if f.first == field_name.to_s}
|
670
725
|
false
|
671
726
|
end
|
727
|
+
=end
|
672
728
|
|
673
729
|
end
|