drg_cms 0.6.1.11 → 0.7.0.2

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.
@@ -116,7 +116,7 @@ def toggle_edit_mode
116
116
  end
117
117
  url << (url.match(/\?/) ? '&' : '?')
118
118
  url << "return_to_ypos=#{ypos}"
119
- redirect_to url
119
+ redirect_to(url, allow_other_host: true)
120
120
  end
121
121
 
122
122
  ####################################################################
@@ -128,15 +128,15 @@ def process_login
128
128
 
129
129
  unless params[:record][:password].blank? #password must not be empty
130
130
  user = DcUser.find_by(username: params[:record][:username], active: true)
131
- if user and user.authenticate(params[:record][:password])
131
+ if user && user.authenticate(params[:record][:password])
132
132
  fill_login_data(user, params[:record][:remember_me].to_i == 1)
133
- return redirect_to params[:return_to] || '/'
133
+ return redirect_to(params[:return_to] || '/', allow_other_host: true)
134
134
  else
135
135
  clear_login_data # on the safe side
136
136
  end
137
137
  end
138
138
  flash[:error] = t('drgcms.invalid_username')
139
- redirect_to params[:return_to_error] || '/'
139
+ redirect_to(params[:return_to] || '/', allow_other_host: true)
140
140
  end
141
141
 
142
142
  ####################################################################
@@ -144,7 +144,7 @@ end
144
144
  ####################################################################
145
145
  def logout
146
146
  clear_login_data
147
- redirect_to params[:return_to] || '/'
147
+ redirect_to(params[:return_to] || '/', allow_other_host: true)
148
148
  end
149
149
 
150
150
  ####################################################################
@@ -156,14 +156,14 @@ def login
156
156
  user = DcUser.find(cookies.signed[:remember_me])
157
157
  if user and user.active
158
158
  fill_login_data(user, true)
159
- return redirect_to params[:return_to]
159
+ return(redirect_to params[:return_to], allow_other_host: true)
160
160
  else
161
161
  clear_login_data # on the safe side
162
162
  end
163
163
  end
164
164
  # Display login
165
165
  route = params[:route] || 'poll'
166
- redirect_to "/#{route}?poll_id=login&return_to=#{params[:return_to]}"
166
+ redirect_to("/#{route}?poll_id=login&return_to=#{params[:return_to]}", allow_other_host: true)
167
167
  end
168
168
 
169
169
  ####################################################################
@@ -0,0 +1,61 @@
1
+ #--
2
+ # Copyright (c) 2014+ Damjan Rems
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ ######################################################################
25
+ # DrgcmsControls for DcPage model.
26
+ ######################################################################
27
+ module DcCategoryControl
28
+
29
+ ######################################################################
30
+ # Called when new empty record is created
31
+ ######################################################################
32
+ def dc_new_record
33
+ if params[:selected]
34
+
35
+ end
36
+ if params[:from_menu]
37
+ # find menu and submenu. Menu class is defined in Site.
38
+ menu_a = params[:id].split(';')
39
+ menu = dc_get_site.menu_klass.find(menu_a.shift)
40
+ menu_items_method = "#{dc_get_site.menu_class}_items".underscore
41
+ menu_i = menu.send(menu_items_method).find(menu_a.shift)
42
+ while menu_a.size > 0 do menu_i = menu_i.send(menu_items_method).find(menu_a.shift) end
43
+ # Fill values for form
44
+ @record.subject = menu_i.caption
45
+ @record.dc_site_id = menu.dc_site_id
46
+ @record.menu_id = params[:id]
47
+ # set update_menu on save parameter
48
+ params['p__update_menu'] = '1'
49
+ else
50
+ @record.design_id = params[:design_id] if params[:design_id]
51
+ return unless params[:page_id]
52
+ # inherit some values from currently active page
53
+ if page = DcPage.find(params[:page_id])
54
+ @record.design_id = page.design_id
55
+ @record.menu = page.menu
56
+ @record.dc_site_id = page.dc_site_id
57
+ end
58
+ end
59
+ end
60
+
61
+ end
@@ -62,12 +62,13 @@ menu:
62
62
  controller: cmsedit
63
63
  icon: more_horiz-o
64
64
  table: dc_simple_menu
65
- 90:
65
+ 90:
66
66
  caption: helpers.label.dc_category.tabletitle
67
67
  controller: cmsedit
68
68
  icon: list
69
69
  table: dc_category
70
- 100:
70
+
71
+ 100:
71
72
  caption: helpers.label.dc_poll.tabletitle
72
73
  controller: cmsedit
73
74
  icon: poll-o
@@ -3,8 +3,17 @@
3
3
  table: dc_category
4
4
 
5
5
  index:
6
- filter: name, description, ctype, parent
7
- actions: standard
6
+ filter: name, description, dc_site_id, parent
7
+ actions:
8
+ 1: new
9
+ 2: filter
10
+ 10:
11
+ type: link
12
+ icon: account_tree-o
13
+ caption: drgcms.category_as_tree
14
+ table: dc_category
15
+ form_name: dc_category_as_tree
16
+ # controller: cmsedit
8
17
 
9
18
  result_set:
10
19
  actions:
@@ -36,13 +45,11 @@ form:
36
45
  10:
37
46
  name: name
38
47
  type: text_field
39
- html:
40
- size: 30
48
+ size: 30
41
49
  20:
42
50
  name: description
43
51
  type: text_field
44
- html:
45
- size: 100
52
+ size: 100
46
53
  30:
47
54
  name: ctype
48
55
  type: select
@@ -51,8 +58,7 @@ form:
51
58
  40:
52
59
  name: order
53
60
  type: text_field
54
- html:
55
- size: 5
61
+ size: 5
56
62
  50:
57
63
  name: dc_site_id
58
64
  type: select
@@ -65,4 +71,7 @@ form:
65
71
  eval: DcCategory.values_for_parent
66
72
  html:
67
73
  include_blank: true
74
+ 70:
75
+ name: active
76
+ type: check_box
68
77
 
@@ -0,0 +1,31 @@
1
+ ## YAML Template for page
2
+ ---
3
+ extend: dc_category
4
+
5
+ index:
6
+ actions:
7
+ 10: /
8
+
9
+ result_set:
10
+ type: method
11
+ eval: categories_as_tree
12
+
13
+ form:
14
+ actions:
15
+ standard: /
16
+ 1:
17
+ type: link
18
+ caption: drgcms.back
19
+ icon: arrow-back
20
+ form_name: dc_category_as_tree
21
+ table: dc_category
22
+ params:
23
+ ids:
24
+ object: params
25
+ method: ids
26
+
27
+ 10:
28
+ type: submit
29
+ caption: 'drgcms.save&back'
30
+ form_name: dc_category_as_tree
31
+ table: dc_category
@@ -0,0 +1,4 @@
1
+ ---
2
+ index: "<p>Updates categories in a Tree view. For edit menu click right mouse button
3
+ over selected category.</p>\r\n"
4
+ form: ''
@@ -0,0 +1,5 @@
1
+ ---
2
+ index: "<p>Urejanje kategorij v drevesnem pogledu. Poi&scaron;čite va&scaron;o kategorijo
3
+ in kliknite desni gumb na mi&scaron;ki za menu.</p>\r\n"
4
+ form: "<p>Urejanje kategorij v drevesnem pogledu. Poi&scaron;čite va&scaron;o kategorijo
5
+ in kliknite desni gumb na mi&scaron;ki za menu.</p>\r\n"
@@ -137,7 +137,7 @@ def dc_actions_for_form(position)
137
137
  actions.delete('standard')
138
138
  actions = actions.to_a.sort { |x, y| x[0] <=> y[0] }
139
139
  # Add spinner to the beginning
140
- html = %Q[<span class="dc-spinner">#{fa_icon('settings-o spin')}</span><ul class="dc-menu #{position}">]
140
+ html = %(<span class="dc-spinner">#{mi_icon('settings-o spin')}</span><ul class="dc-menu #{position}">)
141
141
 
142
142
  actions.each do |key, options|
143
143
  session[:form_processing] = "form:actions: #{key} #{options}"
@@ -211,7 +211,7 @@ def dc_actions_for_form(position)
211
211
  dc_submit_tag(caption, icon, { data: parameters, title: options['title'] }) +
212
212
  '</li>'
213
213
  else
214
- %(<li><div class="dc-link-no">#{fa_icon(icon)} #{caption}</div></li>)
214
+ %(<li><div class="dc-link-no">#{mi_icon(icon)} #{caption}</div></li>)
215
215
  end
216
216
 
217
217
  # delete with some sugar added
@@ -314,50 +314,22 @@ def dc_new_title
314
314
  end
315
315
  end
316
316
 
317
- ####################################################################
318
- # Formats label and html input code for display on edit form.
319
- #
320
- # Parameters:
321
- # [input_html] String. HTML code for data input field.
322
- # [label] String. Input field label.
323
- ####################################################################
324
- def dc_label_for(input_html, label)
325
- c =<<eot
326
- <tr>
327
- <td class="dc-edit-label">#{label}</td>
328
- <td class="dc-edit-field">#{input_html}</td>
329
- </tr>
330
- eot
331
- c.html_safe
332
- end
333
-
334
317
  ############################################################################
335
318
  # Similar to rails submit_tag, but also takes care of link icon, translation, ...
336
319
  ############################################################################
337
- def dc_submit_tag(caption, icon, parms, rest={})
338
- parms['class'] ||= 'dc-link'
339
- if icon
340
- icon_image = if icon.match(/\./)
341
- image_tag(icon)
342
- elsif icon.match('<i')
343
- icon
344
- else
345
- fa_icon(icon)
346
- end
347
- end
348
- html = icon_image || ''
349
- #html << submit_tag(t(caption, caption), parms)
350
- %Q[<button type="submit" class="dc-submit" name="commit" value="#{t(caption, caption)}">#{icon_image} #{t(caption, caption)}</button>].html_safe
320
+ def dc_submit_tag(caption, icon, parms, rest = {})
321
+ icon_image = dc_icon_for_link(icon, nil)
322
+ %(<button type="submit" class="dc-submit" name="commit" value="#{t(caption, caption)}">#{icon_image} #{t(caption, caption)}</button>).html_safe
351
323
  end
352
324
 
353
325
  ############################################################################
354
326
  # Returns icon code if icon is specified
355
327
  ############################################################################
356
- def dc_icon_for_link(icon)
328
+ def dc_icon_for_link(icon, clas = 'dc-link-img')
357
329
  return '' if icon.blank?
358
330
 
359
331
  if icon.match(/\./)
360
- _origin.image_tag(icon, class: 'dc-link-img')
332
+ _origin.image_tag(icon, class: clas)
361
333
  elsif icon.match('<i')
362
334
  icon
363
335
  else
@@ -619,7 +591,7 @@ def dc_page_edit_menu(opts = @opts)
619
591
  opts[:editparams] ||= {}
620
592
  dc_link_menu_tag(title) do |html|
621
593
  opts[:editparams].merge!( controller: 'cmsedit', action: 'edit', 'icon' => 'edit-o' )
622
- opts[:editparams].merge!( :id => page.id, :t => _origin.site.page_class.underscore, f: opts[:form_name], edit_only: 'body' )
594
+ opts[:editparams].merge!( :id => page.id, :table => _origin.site.page_class.underscore, form_name: opts[:form_name], edit_only: 'body' )
623
595
  html << dc_link_for_edit1( opts[:editparams], t('drgcms.edit_content') )
624
596
 
625
597
  opts[:editparams].merge!( edit_only: nil, 'icon' => 'edit-o' )
@@ -867,7 +839,7 @@ end
867
839
  #
868
840
  # Parameters:
869
841
  # [ctrl] Controller object or object which holds methods to access session object. For example @parent
870
- # variable when called from renderer.
842
+ # when called from renderer.
871
843
  # [policy_id] Document or documents policy_id field value required to view data. Method will automatically
872
844
  # check if parameter send has policy_id field defined and use value of that field.
873
845
  #
@@ -882,9 +854,11 @@ end
882
854
  # False and message from policy that is blocking view if access is not allowed.
883
855
  ############################################################################
884
856
  def dc_user_can_view(ctrl, policy_id)
885
- policy_id = policy_id.policy_id if policy_id and policy_id.respond_to?(:policy_id)
857
+ @can_view_cache ||= {}
858
+ policy_id = policy_id.policy_id if policy_id&.respond_to?(:policy_id)
886
859
  # Eventualy object without policy_id will be checked. This is to prevent error
887
860
  policy_id = nil unless policy_id.class == BSON::ObjectId
861
+ return @can_view_cache[policy_id] if @can_view_cache[policy_id]
888
862
 
889
863
  site = ctrl.site
890
864
  policies = if site.inherit_policy.blank?
@@ -894,7 +868,7 @@ def dc_user_can_view(ctrl, policy_id)
894
868
  end
895
869
  # permission defined by default policy
896
870
  default_policy = Mongoid::QueryCache.cache { policies.find_by(is_default: true) }
897
- return false, 'Default access policy not found for the site!' unless default_policy
871
+ return cache_add(policy_id, false, 'Default access policy not found for the site!') unless default_policy
898
872
 
899
873
  permissions = {}
900
874
  default_policy.dc_policy_rules.to_a.each { |v| permissions[v.dc_policy_role_id] = v.permission }
@@ -902,28 +876,29 @@ def dc_user_can_view(ctrl, policy_id)
902
876
  part_policy = nil
903
877
  if policy_id
904
878
  part_policy = Mongoid::QueryCache.cache { policies.find(policy_id) }
905
- return false, 'Access policy not found for part!' unless part_policy
879
+ return cache_add(policy_id, false, 'Access policy not found for part!') unless part_policy
880
+
906
881
  part_policy.dc_policy_rules.to_a.each { |v| permissions[v.dc_policy_role_id] = v.permission }
907
882
  end
908
883
  # apply guest role if no roles defined
909
884
  if ctrl.session[:user_roles].nil?
910
885
  role = Mongoid::QueryCache.cache { DcPolicyRole.find_by(system_name: 'guest', active: true) }
911
- return false, 'System guest role not defined!' unless role
886
+ return cache_add(policy_id, false, 'System guest role not defined!') unless role
887
+
912
888
  ctrl.session[:user_roles] = [role.id]
913
889
  end
914
890
  # Check if user has any role that allows him to view part
915
- can_view, msg = false,''
916
- ctrl.session[:user_roles].each do |role|
917
- next unless permissions[role] # role not yet defined. Will die in next line.
918
- if permissions[role] > 0
919
- can_view = true
920
- break
921
- end
891
+ can_view = ctrl.session[:user_roles].reduce(false) do |result, role|
892
+ break true if permissions[role] && permissions[role] > 0
922
893
  end
923
- msg = if !can_view
924
- part_policy ? t(part_policy.message,part_policy.message) : t(default_policy.message,default_policy.message)
894
+
895
+ msg = ''
896
+ unless can_view
897
+ msg = part_policy ? t(part_policy.message, part_policy.message) : t(default_policy.message, default_policy.message)
898
+ # message may have variable content
899
+ msg = _origin.render(inline: msg, layout: nil) if msg.match('<%=')
925
900
  end
926
- return can_view, msg
901
+ cache_add(policy_id, can_view, msg)
927
902
  end
928
903
 
929
904
  ####################################################################
@@ -1234,5 +1209,12 @@ def dc_img_alt(file_name, text=nil)
1234
1209
  name[0,name.index('.')].downcase rescue name
1235
1210
  end
1236
1211
 
1212
+ private
1213
+
1214
+ # will cache dc_user_can_view response
1215
+ def cache_add(id, can_view, msg)
1216
+ @can_view_cache[id] = [can_view, msg]
1217
+ end
1218
+
1237
1219
 
1238
1220
  end
@@ -0,0 +1,129 @@
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
+
24
+
25
+ ####################################################################
26
+ # Helper for editing categories as tree view.
27
+ ####################################################################
28
+ module DcCategoryHelper
29
+
30
+ ####################################################################
31
+ #
32
+ ####################################################################
33
+ def categories_as_tree
34
+ html = '<div id="catagories-as-tree"><ul><li data-id="nil"><span class="mi-o mi-home"></span>'
35
+ data = DcCategory.where(parent: nil).order_by(order: 1).to_a
36
+ html_for_category_tree(html, data)
37
+ (html << '</li></ul></div>' << js_for_category_tree).html_safe
38
+ end
39
+
40
+ private
41
+
42
+ ####################################################################
43
+ #
44
+ ####################################################################
45
+ def html_for_category_tree(html, data)
46
+ html << '<ul>'
47
+ data.each do |category|
48
+ icon = category.active ? 'check_box' : 'check_box_outline_blank'
49
+ html << %(<li id="#{category.id}" data-parent="#{category.parent}"><span class="mi-o mi-#{icon} mi-18"></span>#{category.name}\n)
50
+ children = DcCategory.where(parent: category.id).order_by(order: 1).to_a
51
+
52
+ html_for_category_tree(html, children) if children.size > 0
53
+ html << '</li>'
54
+ end
55
+ html << '</ul>'
56
+ end
57
+
58
+ ####################################################################
59
+ #
60
+ ####################################################################
61
+ def js_for_category_tree
62
+ %(<script>
63
+ $(function() {
64
+ $("#catagories-as-tree").jstree( {
65
+ core: { themes: { icons: false },
66
+ multiple: false
67
+ },
68
+ plugins: ["types", "contextmenu"],
69
+ contextmenu: {
70
+ items: function ($node) {
71
+ return {
72
+ edit: {
73
+ label: "<span class='dc-result-submenu'>#{t('drgcms.edit')}</span>",
74
+ icon: "mi-o mi-edit",
75
+ action: function (obj) {
76
+ let id = $('#catagories-as-tree').jstree('get_selected', true)[0].id;
77
+ let params = "&ids=" + id;
78
+ location.href = "/cmsedit/" + id + "/edit?t=dc_category&f=dc_category_as_tree" + params;
79
+ }
80
+ },
81
+
82
+ new_child: {
83
+ label: "<span class='dc-result-submenu'>#{t('drgcms.new')}</span>",
84
+ icon: "mi-o mi-plus",
85
+ action: function (obj) {
86
+ let id = $('#catagories-as-tree').jstree('get_selected', true)[0].id;
87
+ let params = "&ids=" + id + "&p_parent=" + id;
88
+ location.href = "/cmsedit/new?t=dc_category&f=dc_category_as_tree" + params
89
+ }
90
+ },
91
+
92
+ delete: {
93
+ label: "<span class='dc-result-submenu'>#{t('drgcms.delete')}</span>",
94
+ icon: "mi-o mi-delete",
95
+ action: function (obj) {
96
+ if (confirmation_is_cancled("#{t('drgcms.confirm_delete')}") === true) return false;
97
+
98
+ let id = $('#catagories-as-tree').jstree('get_selected', true)[0].id;
99
+ let id_return = $('#catagories-as-tree').jstree('get_selected', true)[0].data["parent"];
100
+
101
+ $.ajax({
102
+ url: "/cmsedit/" + id + "?t=dc_category",
103
+ type: 'DELETE',
104
+ success: function(data) {
105
+ let error = data.match("#{I18n.t('drgcms.category_has_subs')}");
106
+ if (error !== null) {
107
+ alert(error[0]);
108
+ params = "?t=dc_category&f=dc_category_as_tree&ids=" + id;
109
+ location.href = "/cmsedit" + params;
110
+ return true;
111
+ }
112
+ }
113
+ });
114
+
115
+ let params = "?t=dc_category&f=dc_category_as_tree&ids=" + id_return;
116
+ location.href = "/cmsedit" + params;
117
+ }
118
+ },
119
+ }
120
+ },
121
+ },
122
+ });
123
+ $("#catagories-as-tree").jstree(true).select_node("#{params[:ids]}");
124
+ });
125
+
126
+ </script>)
127
+ end
128
+
129
+ end
@@ -42,32 +42,60 @@
42
42
  # is most useful for grouping news, blog entries ...
43
43
  #####################################################################
44
44
  class DcCategory
45
- include Mongoid::Document
46
- include Mongoid::Timestamps
45
+ include Mongoid::Document
46
+ include Mongoid::Timestamps
47
47
 
48
- field :name, type: String
49
- field :description, type: String
50
- field :ctype, type: Integer, default: 1
51
- field :parent, type: BSON::ObjectId
52
- field :active, type: Boolean, default: true
53
- field :order, type: Integer, default: 0
54
- field :created_by, type: BSON::ObjectId
55
- field :updated_by, type: BSON::ObjectId
56
- field :dc_site_id, type: BSON::ObjectId
48
+ field :name, type: String
49
+ field :description, type: String
50
+ field :ctype, type: Integer, default: 1
51
+ field :parent, type: BSON::ObjectId
52
+ field :active, type: Boolean, default: true
53
+ field :order, type: Integer, default: 0
54
+ field :created_by, type: BSON::ObjectId
55
+ field :updated_by, type: BSON::ObjectId
56
+ field :dc_site_id, type: BSON::ObjectId
57
57
 
58
- validates :name, :presence => true
59
-
60
- index name: 1
61
- index ctype: 1
62
- index site_id: 1
58
+ index name: 1
59
+ index ctype: 1
60
+ index site_id: 1
61
+
62
+ validates :name, presence: true
63
+
64
+ before_destroy :can_destroy?
65
+
66
+ private
67
+
68
+ #########################################################################
69
+ # Can't delete if category document has children documents
70
+ #########################################################################
71
+ def can_destroy?
72
+ if DcCategory.where(parent: id).count > 0
73
+ errors.add(:base, I18n.t('drgcms.category_has_subs'))
74
+ throw :abort
75
+ end
76
+ end
63
77
 
64
78
  #########################################################################
65
- # Returns all values vhich can be used as parent select field.
79
+ # Returns all values for use as parent select field.
66
80
  #########################################################################
67
- def self.values_for_parent(site_id=nil) #:nodoc:
81
+ def self.values_for_parent(site_id = nil) #:nodoc:
68
82
  qry = where(active: true)
69
83
  qry = qry.and(dc_site_id: site_id.id) if site_id
70
- qry.sort(name: 1).inject([]) {|r,v| r << [v.name, v._id]}
84
+ parents = {} # cache parent names to minimize database usage
85
+ qry.inject([]) do |r, v|
86
+ if parents[v.parent].nil?
87
+ name = ''
88
+ parent = v.parent
89
+ until parent.nil?
90
+ doc = find(parent)
91
+ name = doc.name + ' / ' + name
92
+ parent = doc.parent
93
+ end
94
+ parents[v.parent] = name
95
+ end
96
+ name = v.parent ? parents[v.parent] + v.name : v.name
97
+ r << [name, v._id]
98
+ end.sort { |a, b| a.first <=> b.first }
71
99
  end
72
100
 
73
101
  #########################################################################
@@ -80,8 +108,8 @@ def self.choices4_ctype(site_id=nil)
80
108
  DcBigTable.choices4('dc_category_type', site_id)
81
109
  else
82
110
  opts = I18n.t('helpers.label.dc_category.choices4_ctype')
83
- # not defined
84
- return [] if opts.blank?
111
+ return [] if opts.blank? # not defined
112
+
85
113
  opts.split(',').inject([]) {|result, e| result << e.split(':')}
86
114
  end
87
115
  end
@@ -89,13 +117,11 @@ end
89
117
  #########################################################################
90
118
  # Returns choices for all categories, prepared for tree_select input field
91
119
  #########################################################################
92
- def self.choices4_categories(site_id=nil)
120
+ def self.choices4_categories(site_id = nil)
93
121
  qry = where(active: true)
94
- #
95
122
  ar = [nil]
96
123
  ar << site_id.id if site_id
97
124
  qry = qry.in(dc_site_id: ar)
98
- #
99
125
  qry.inject([]) { |result, category| result << [category.name, category.id, category.parent, category.order] }
100
126
  end
101
127
 
@@ -66,30 +66,28 @@ class DatePicker < DrgcmsField
66
66
  ###########################################################################
67
67
  def render
68
68
  value = @record.try(@yaml['name']) ? I18n.localize(@record[@yaml['name']].to_date) : nil
69
- #return ro_standard( @parent.dc_format_value(value)) if @readonly
70
-
71
- @yaml['options'] ||= {}
72
69
  set_initial_value
73
70
  @yaml['html']['size'] ||= @yaml['size'] || 10
74
71
  @yaml['html']['value'] ||= value
75
72
  @yaml['html']['autocomplete'] ||= 'off'
76
73
  @yaml['html']['class'] = @yaml['html']['class'].to_s + ' date-picker'
77
74
 
78
- @yaml['options']['lang'] ||= "'#{I18n.locale}'"
79
- @yaml['options']['format'] ||= "'#{t('datetimepicker.formats.date')}'"
80
- @yaml['options']['timepicker'] = false
81
- @yaml['options']['scrollMonth'] ||= false
82
- @yaml['options']['scrollInput'] ||= false
75
+ options = options_to_hash(@yaml['options'])
76
+ options['lang'] ||= I18n.locale.to_s
77
+ options['format'] ||= t('datetimepicker.formats.date')
78
+ options['timepicker'] = false
79
+ options['scrollMonth'] ||= false
80
+ options['scrollInput'] ||= false
83
81
 
84
82
  record = record_text_for(@yaml['name'])
85
83
  @html << @parent.text_field(record, @yaml['name'], @yaml['html'])
86
- @js << %Q[
84
+ @js << %(
87
85
  $(document).ready(function() {
88
- $("##{record}_#{@yaml['name']}").datetimepicker( {
89
- #{hash_to_options(@yaml['options'])}
86
+ $("##{record}_#{@yaml['name']}").datetimepicker({
87
+ #{hash_to_options(options)}
90
88
  });
91
89
  });
92
- ] unless @readonly
90
+ ) unless @readonly
93
91
 
94
92
  self
95
93
  end