Description:
prepare for better hall of fame
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r425:b86f327e0d75 - - 8 files changed: 46 inserted, 70 deleted

@@ -1,33 +1,38
1 class ApplicationController < ActionController::Base
1 class ApplicationController < ActionController::Base
2 protect_from_forgery
2 protect_from_forgery
3
3
4 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
4 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
5
5
6 def admin_authorization
6 def admin_authorization
7 return false unless authenticate
7 return false unless authenticate
8 user = User.find(session[:user_id], :include => ['roles'])
8 user = User.find(session[:user_id], :include => ['roles'])
9 - redirect_to :controller => 'main', :action => 'login' unless user.admin?
9 + unless user.admin?
10 + flash[:notice] = 'You are not authorized to view the page you requested'
11 + redirect_to :controller => 'main', :action => 'login' unless user.admin?
12 + return false
13 + end
14 + return true
10 end
15 end
11
16
12 def authorization_by_roles(allowed_roles)
17 def authorization_by_roles(allowed_roles)
13 return false unless authenticate
18 return false unless authenticate
14 user = User.find(session[:user_id])
19 user = User.find(session[:user_id])
15 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
20 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
16 flash[:notice] = 'You are not authorized to view the page you requested'
21 flash[:notice] = 'You are not authorized to view the page you requested'
17 redirect_to :controller => 'main', :action => 'login'
22 redirect_to :controller => 'main', :action => 'login'
18 return false
23 return false
19 end
24 end
20 end
25 end
21
26
22 protected
27 protected
23
28
24 def authenticate
29 def authenticate
25 unless session[:user_id]
30 unless session[:user_id]
26 flash[:notice] = 'You need to login'
31 flash[:notice] = 'You need to login'
27 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
32 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
28 flash[:notice] = 'You need to login but you cannot log in at this time'
33 flash[:notice] = 'You need to login but you cannot log in at this time'
29 end
34 end
30 redirect_to :controller => 'main', :action => 'login'
35 redirect_to :controller => 'main', :action => 'login'
31 return false
36 return false
32 end
37 end
33
38
@@ -1,27 +1,36
1 class GradersController < ApplicationController
1 class GradersController < ApplicationController
2
2
3 - before_filter :admin_authorization
3 + before_filter :admin_authorization, except: [ :submission ]
4 + before_filter(only: [:submission]) {
5 + return false unless authenticate
6 +
7 + if GraderConfiguration["right.user_view_submission"]
8 + return true;
9 + end
10 +
11 + admin_authorization
12 + }
4
13
5 verify :method => :post, :only => ['clear_all',
14 verify :method => :post, :only => ['clear_all',
6 'start_exam',
15 'start_exam',
7 'start_grading',
16 'start_grading',
8 'stop_all',
17 'stop_all',
9 'clear_terminated'],
18 'clear_terminated'],
10 :redirect_to => {:action => 'index'}
19 :redirect_to => {:action => 'index'}
11
20
12 def index
21 def index
13 redirect_to :action => 'list'
22 redirect_to :action => 'list'
14 end
23 end
15
24
16 def list
25 def list
17 @grader_processes = GraderProcess.find_running_graders
26 @grader_processes = GraderProcess.find_running_graders
18 @stalled_processes = GraderProcess.find_stalled_process
27 @stalled_processes = GraderProcess.find_stalled_process
19
28
20 @terminated_processes = GraderProcess.find_terminated_graders
29 @terminated_processes = GraderProcess.find_terminated_graders
21
30
22 @last_task = Task.find(:first,
31 @last_task = Task.find(:first,
23 :order => 'created_at DESC')
32 :order => 'created_at DESC')
24 @last_test_request = TestRequest.find(:first,
33 @last_test_request = TestRequest.find(:first,
25 :order => 'created_at DESC')
34 :order => 'created_at DESC')
26 end
35 end
27
36
@@ -1,31 +1,31
1 class ReportController < ApplicationController
1 class ReportController < ApplicationController
2
2
3 before_filter :admin_authorization, only: [:login_stat,:submission_stat]
3 before_filter :admin_authorization, only: [:login_stat,:submission_stat]
4 - before_filter { |c|
4 + before_filter(only: [:problem_hof]) { |c|
5 return false unless authenticate
5 return false unless authenticate
6
6
7 - if GraderConfiguration["system.hall_of_fame_available"]
7 + if GraderConfiguration["right.user_view_submission"]
8 return true;
8 return true;
9 end
9 end
10
10
11 admin_authorization
11 admin_authorization
12 }
12 }
13
13
14 def login_stat
14 def login_stat
15 @logins = Array.new
15 @logins = Array.new
16
16
17 date_and_time = '%Y-%m-%d %H:%M'
17 date_and_time = '%Y-%m-%d %H:%M'
18 begin
18 begin
19 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
19 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
20 rescue
20 rescue
21 @since_time = DateTime.new(1000,1,1)
21 @since_time = DateTime.new(1000,1,1)
22 end
22 end
23 begin
23 begin
24 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
24 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
25 rescue
25 rescue
26 @until_time = DateTime.new(3000,1,1)
26 @until_time = DateTime.new(3000,1,1)
27 end
27 end
28
28
29 User.all.each do |user|
29 User.all.each do |user|
30 @logins << { login: user.login,
30 @logins << { login: user.login,
31 full_name: user.full_name,
31 full_name: user.full_name,
@@ -135,53 +135,53
135 end
135 end
136
136
137 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value]
137 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value]
138 @by_lang[lang.pretty_name][:first] = {
138 @by_lang[lang.pretty_name][:first] = {
139 avail: true,
139 avail: true,
140 user_id: sub.user_id,
140 user_id: sub.user_id,
141 value: sub.submitted_at,
141 value: sub.submitted_at,
142 sub_id: sub.id
142 sub_id: sub.id
143 }
143 }
144 end
144 end
145
145
146 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
146 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
147 @by_lang[lang.pretty_name][:length] = {
147 @by_lang[lang.pretty_name][:length] = {
148 avail: true,
148 avail: true,
149 user_id: sub.user_id,
149 user_id: sub.user_id,
150 value: sub.effective_code_length,
150 value: sub.effective_code_length,
151 sub_id: sub.id
151 sub_id: sub.id
152 }
152 }
153 end
153 end
154 end
154 end
155
155
156 #process user_id
156 #process user_id
157 @by_lang.each do |lang,prop|
157 @by_lang.each do |lang,prop|
158 prop.each do |k,v|
158 prop.each do |k,v|
159 - v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).login : "(NULL)"
159 + v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
160 end
160 end
161 end
161 end
162
162
163 #sum into best
163 #sum into best
164 if @by_lang and @by_lang.first
164 if @by_lang and @by_lang.first
165 @best = @by_lang.first[1]
165 @best = @by_lang.first[1]
166 @by_lang.each do |lang,prop|
166 @by_lang.each do |lang,prop|
167 - if @best[:runtime][:value] > prop[:runtime][:value]
167 + if @best[:runtime][:value] >= prop[:runtime][:value]
168 @best[:runtime] = prop[:runtime]
168 @best[:runtime] = prop[:runtime]
169 @best[:runtime][:lang] = lang
169 @best[:runtime][:lang] = lang
170 end
170 end
171 - if @best[:memory][:value] > prop[:memory][:value]
171 + if @best[:memory][:value] >= prop[:memory][:value]
172 @best[:memory] = prop[:memory]
172 @best[:memory] = prop[:memory]
173 @best[:memory][:lang] = lang
173 @best[:memory][:lang] = lang
174 end
174 end
175 - if @best[:length][:value] > prop[:length][:value]
175 + if @best[:length][:value] >= prop[:length][:value]
176 @best[:length] = prop[:length]
176 @best[:length] = prop[:length]
177 @best[:length][:lang] = lang
177 @best[:length][:lang] = lang
178 end
178 end
179 - if @best[:first][:value] > prop[:first][:value]
179 + if @best[:first][:value] >= prop[:first][:value]
180 @best[:first] = prop[:first]
180 @best[:first] = prop[:first]
181 @best[:first][:lang] = lang
181 @best[:first][:lang] = lang
182 end
182 end
183 end
183 end
184 end
184 end
185 end
185 end
186 end
186 end
187 end
187 end
@@ -10,49 +10,49
10 menu_items << "<b>Administrative task:</b> "
10 menu_items << "<b>Administrative task:</b> "
11 append_to menu_items, '[Announcements]', 'announcements', 'index'
11 append_to menu_items, '[Announcements]', 'announcements', 'index'
12 append_to menu_items, '[Msg console]', 'messages', 'console'
12 append_to menu_items, '[Msg console]', 'messages', 'console'
13 append_to menu_items, '[Problems]', 'problems', 'index'
13 append_to menu_items, '[Problems]', 'problems', 'index'
14 append_to menu_items, '[Users]', 'user_admin', 'index'
14 append_to menu_items, '[Users]', 'user_admin', 'index'
15 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
15 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
16 append_to menu_items, '[Report]', 'report', 'login_stat'
16 append_to menu_items, '[Report]', 'report', 'login_stat'
17 append_to menu_items, '[Graders]', 'graders', 'list'
17 append_to menu_items, '[Graders]', 'graders', 'list'
18 append_to menu_items, '[Contests]', 'contest_management', 'index'
18 append_to menu_items, '[Contests]', 'contest_management', 'index'
19 append_to menu_items, '[Sites]', 'sites', 'index'
19 append_to menu_items, '[Sites]', 'sites', 'index'
20 append_to menu_items, '[System config]', 'configurations', 'index'
20 append_to menu_items, '[System config]', 'configurations', 'index'
21 menu_items << "<br/>"
21 menu_items << "<br/>"
22 end
22 end
23
23
24 # main page
24 # main page
25 append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
25 append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
26 append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
26 append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
27
27
28 if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
28 if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
29 append_to menu_items, "[#{I18n.t 'menu.tasks'}]", 'tasks', 'list'
29 append_to menu_items, "[#{I18n.t 'menu.tasks'}]", 'tasks', 'list'
30 append_to menu_items, "[#{I18n.t 'menu.submissions'}]", 'main', 'submission'
30 append_to menu_items, "[#{I18n.t 'menu.submissions'}]", 'main', 'submission'
31 append_to menu_items, "[#{I18n.t 'menu.test'}]", 'test', 'index'
31 append_to menu_items, "[#{I18n.t 'menu.test'}]", 'test', 'index'
32 end
32 end
33
33
34 - if GraderConfiguration['system.hall_of_fame_available']
34 + if GraderConfiguration['right.user_hall_of_fame']
35 append_to menu_items, "[#{I18n.t 'menu.hall_of_fame'}]", 'report', 'problem_hof'
35 append_to menu_items, "[#{I18n.t 'menu.hall_of_fame'}]", 'report', 'problem_hof'
36 end
36 end
37 append_to menu_items, "[#{I18n.t 'menu.help'}]", 'main', 'help'
37 append_to menu_items, "[#{I18n.t 'menu.help'}]", 'main', 'help'
38
38
39 if GraderConfiguration['system.user_setting_enabled']
39 if GraderConfiguration['system.user_setting_enabled']
40 append_to menu_items, "[#{I18n.t 'menu.settings'}]", 'users', 'index'
40 append_to menu_items, "[#{I18n.t 'menu.settings'}]", 'users', 'index'
41 end
41 end
42 append_to menu_items, "[#{I18n.t 'menu.log_out'}]", 'main', 'login'
42 append_to menu_items, "[#{I18n.t 'menu.log_out'}]", 'main', 'login'
43
43
44 menu_items.html_safe
44 menu_items.html_safe
45 end
45 end
46
46
47 def append_to(option,label, controller, action)
47 def append_to(option,label, controller, action)
48 option << ' ' if option!=''
48 option << ' ' if option!=''
49 option << link_to_unless_current(label,
49 option << link_to_unless_current(label,
50 :controller => controller,
50 :controller => controller,
51 :action => action)
51 :action => action)
52 end
52 end
53
53
54 def format_short_time(time)
54 def format_short_time(time)
55 now = Time.now.gmtime
55 now = Time.now.gmtime
56 st = ''
56 st = ''
57 if (time.yday != now.yday) or
57 if (time.yday != now.yday) or
58 (time.year != now.year)
58 (time.year != now.year)
@@ -1,27 +1,27
1 %style{type: "text/css"}
1 %style{type: "text/css"}
2 = @css_style
2 = @css_style
3
3
4 %h1= "Submission: #{@submission.id}"
4 %h1= "Submission: #{@submission.id}"
5
5
6 %p
6 %p
7 User:
7 User:
8 - = "#{@submission.user.login}"
8 + = "(#{@submission.user.login}) #{@submission.user.full_name}"
9 %br/
9 %br/
10 Problem:
10 Problem:
11 - if @submission.problem!=nil
11 - if @submission.problem!=nil
12 = "#{@submission.problem.full_name}"
12 = "#{@submission.problem.full_name}"
13 - else
13 - else
14 = "(n/a)"
14 = "(n/a)"
15 %br/
15 %br/
16 = "Number: #{@submission.number}"
16 = "Number: #{@submission.number}"
17 %br/
17 %br/
18 = "Submitted at: #{format_short_time(@submission.submitted_at)}"
18 = "Submitted at: #{format_short_time(@submission.submitted_at)}"
19 %br/
19 %br/
20 = "Points : #{@submission.points}/#{@submission.problem.full_score}"
20 = "Points : #{@submission.points}/#{@submission.problem.full_score}"
21 %br/
21 %br/
22 = "Comment : #{@submission.grader_comment}"
22 = "Comment : #{@submission.grader_comment}"
23
23
24 %b Source code (first 10kb)
24 %b Source code (first 10kb)
25 //%div.highlight{:style => "border: 1px solid black;"}
25 //%div.highlight{:style => "border: 1px solid black;"}
26 =@formatted_code.html_safe
26 =@formatted_code.html_safe
27
27
@@ -1,33 +1,31
1 - content_for :header do
1 - content_for :header do
2 = javascript_include_tag 'new'
2 = javascript_include_tag 'new'
3
3
4 %script{:type=>"text/javascript"}
4 %script{:type=>"text/javascript"}
5 $(function () {
5 $(function () {
6 $('#since_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
6 $('#since_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
7 $('#until_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
7 $('#until_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
8 });
8 });
9
9
10 -
11 %h1 Login status
10 %h1 Login status
12
11
13 -
14 =render partial: 'report_menu'
12 =render partial: 'report_menu'
15 =render partial: 'date_range', locals: {param_text: 'Login date range:', title: 'Query login stat in the range' }
13 =render partial: 'date_range', locals: {param_text: 'Login date range:', title: 'Query login stat in the range' }
16
14
17 %table.info
15 %table.info
18 %thead
16 %thead
19 %tr.info-head
17 %tr.info-head
20 %th login
18 %th login
21 %th full name
19 %th full name
22 %th login count
20 %th login count
23 %th earliest
21 %th earliest
24 %th latest
22 %th latest
25 %tbody
23 %tbody
26 - @logins.each do |l|
24 - @logins.each do |l|
27 %tr{class: cycle('info-even','info-odd')}
25 %tr{class: cycle('info-even','info-odd')}
28 %td= l[:login]
26 %td= l[:login]
29 %td= l[:full_name]
27 %td= l[:full_name]
30 %td= l[:count]
28 %td= l[:count]
31 %td= l[:min] ? l[:min].in_time_zone.strftime('%Y-%m-%d %H:%M') : ''
29 %td= l[:min] ? l[:min].in_time_zone.strftime('%Y-%m-%d %H:%M') : ''
32 %td= l[:max] ? l[:max].in_time_zone.strftime('%Y-%m-%d %H:%M') : ''
30 %td= l[:max] ? l[:max].in_time_zone.strftime('%Y-%m-%d %H:%M') : ''
33
31
@@ -1,65 +1,22
1 +
2 + /- if params[:id]
3 + / %h1 Tasks Hall of Fame
4 + / = link_to('[back to All-Time Hall of Fame]', action: 'problem_hof', id: nil )
5 + /- else
6 + / %h1 All-Time Hall of Fame
7 +
8 +
1 %h1 Tasks Hall of Fame
9 %h1 Tasks Hall of Fame
2 -
3 .task-menu
10 .task-menu
4 Tasks
11 Tasks
5 %br/
12 %br/
6 - @problems.each do |prob|
13 - @problems.each do |prob|
7 = link_to( "[#{prob.name}]", {id: prob.id})
14 = link_to( "[#{prob.name}]", {id: prob.id})
8
15
9 -
16 + - unless params[:id]
10 -
17 + /=render partial: 'all_time_hof'
11 -
18 + Please select a problem.
12 - %h2 Overall
19 + - else
13 -
20 + =render partial: 'task_hof'
14 - - if @best
15 - %b Best Runtime:
16 - = " by #{@best[:runtime][:user]} with #{@best[:runtime][:value] * 1000} milliseconds at submission " \
17 - = link_to("#" + @best[:runtime][:sub_id].to_s, controller: 'graders', action: 'submission', id:@best[:runtime][:sub_id])
18 - %br/
19 - %b Best Memory Usage:
20 - = " by #{@best[:memory][:user]} with #{@best[:memory][:value]} kbytes at submission "
21 - = link_to("#" + @best[:memory][:sub_id].to_s, controller: 'graders' , action: 'submission', id:@best[:memory][:sub_id])
22 - %br/
23 - %b Shortest Code:
24 - = " by #{@best[:length][:user]} with #{@best[:length][:value]} at submission "
25 - = link_to("#" + @best[:length][:sub_id].to_s, controller: 'graders' , action: 'submission', id: @best[:length][:sub_id])
26 - %br/
27 - %b First solver:
28 - = " by #{@best[:first][:user]} is the first solver on #{@best[:first][:value]} at submission "
29 - = link_to("#" + @best[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: @best[:first][:sub_id])
30 - %br/
31
21
32
22
33 - %p
34 - This counts only for submission with 100% score <br/>
35 - Right now, java is excluded from memory usage competition. (Because it always uses 2GB memory...)
36 -
37 - %h2 By language
38 -
39 - %table.info
40 - %thead
41 - %tr.info-head
42 - %th Language
43 - %th Best runtime (ms)
44 - %th Best memory (kbytes)
45 - %th Shortest Code (bytes)
46 - %th First solver
47 - %tbody
48 - - @by_lang.each do |lang,value|
49 - %tr{class: cycle('info-even','info-odd')}
50 - %td= lang
51 - %td
52 - = "#{value[:runtime][:user]} (#{(value[:runtime][:value] * 1000).to_i} @"
53 - = "#{link_to("#" + value[:runtime][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:runtime][:sub_id])} )".html_safe
54 - %td
55 - = "#{value[:memory][:user]} (#{value[:memory][:value]} @"
56 - = "#{link_to("#" + value[:memory][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:memory][:sub_id])} )".html_safe
57 - %td
58 - = "#{value[:length][:user]} (#{value[:length][:value]} @"
59 - = "#{link_to("#" + value[:length][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:length][:sub_id])} )".html_safe
60 - %td
61 - = "#{value[:first][:user]} (#{value[:first][:value]} @"
62 - = "#{link_to("#" + value[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:first][:sub_id])} )".html_safe
63 -
64 - - else
65 - %h3 No submissions
@@ -33,54 +33,61
33 },
33 },
34
34
35 {
35 {
36 :key => 'system.mode',
36 :key => 'system.mode',
37 :value_type => 'string',
37 :value_type => 'string',
38 :default_value => 'standard',
38 :default_value => 'standard',
39 :description => 'Current modes are "standard", "contest", "indv-contest", and "analysis".'
39 :description => 'Current modes are "standard", "contest", "indv-contest", and "analysis".'
40 },
40 },
41
41
42 {
42 {
43 :key => 'contest.name',
43 :key => 'contest.name',
44 :value_type => 'string',
44 :value_type => 'string',
45 :default_value => 'Grader',
45 :default_value => 'Grader',
46 :description => 'This name will be shown on the user header bar.'
46 :description => 'This name will be shown on the user header bar.'
47 },
47 },
48
48
49 {
49 {
50 :key => 'contest.multisites',
50 :key => 'contest.multisites',
51 :value_type => 'boolean',
51 :value_type => 'boolean',
52 :default_value => 'false',
52 :default_value => 'false',
53 :description => 'If the server is in contest mode and this option is true, on the log in of the admin a menu for site selections is shown.'
53 :description => 'If the server is in contest mode and this option is true, on the log in of the admin a menu for site selections is shown.'
54 },
54 },
55
55
56 {
56 {
57 - :key => 'system.hall_of_fame_available',
57 + :key => 'right.user_hall_of_fame',
58 :value_type => 'boolean',
58 :value_type => 'boolean',
59 :default_value => 'false',
59 :default_value => 'false',
60 :description => 'If true, any user can access hall of fame page.'
60 :description => 'If true, any user can access hall of fame page.'
61 },
61 },
62
62
63 + {
64 + :key => 'right.user_view_submission',
65 + :value_type => 'boolean',
66 + :default_value => 'false',
67 + :description => 'If true, any user can view submissions of every one.'
68 + },
69 +
63 # If Configuration['system.online_registration'] is true, the
70 # If Configuration['system.online_registration'] is true, the
64 # system allows online registration, and will use these
71 # system allows online registration, and will use these
65 # information for sending confirmation emails.
72 # information for sending confirmation emails.
66 {
73 {
67 :key => 'system.online_registration.smtp',
74 :key => 'system.online_registration.smtp',
68 :value_type => 'string',
75 :value_type => 'string',
69 :default_value => 'smtp.somehost.com'
76 :default_value => 'smtp.somehost.com'
70 },
77 },
71
78
72 {
79 {
73 :key => 'system.online_registration.from',
80 :key => 'system.online_registration.from',
74 :value_type => 'string',
81 :value_type => 'string',
75 :default_value => 'your.email@address'
82 :default_value => 'your.email@address'
76 },
83 },
77
84
78 {
85 {
79 :key => 'system.admin_email',
86 :key => 'system.admin_email',
80 :value_type => 'string',
87 :value_type => 'string',
81 :default_value => 'admin@admin.email'
88 :default_value => 'admin@admin.email'
82 },
89 },
83
90
84 {
91 {
85 :key => 'system.user_setting_enabled',
92 :key => 'system.user_setting_enabled',
86 :value_type => 'boolean',
93 :value_type => 'boolean',
You need to be logged in to leave comments. Login now