##// END OF EJS Templates
Dry Users API responders....
Jean-Philippe Lang -
r4340:ea59d93dc82d
parent child
Show More
@@ -1,229 +1,225
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class UsersController < ApplicationController
19 19 layout 'admin'
20 20
21 21 before_filter :require_admin, :except => :show
22 22 accept_key_auth :index, :show, :create, :update
23 23
24 24 helper :sort
25 25 include SortHelper
26 26 helper :custom_fields
27 27 include CustomFieldsHelper
28 28
29 29 def index
30 30 sort_init 'login', 'asc'
31 31 sort_update %w(login firstname lastname mail admin created_on last_login_on)
32 32
33 33 @status = params[:status] ? params[:status].to_i : 1
34 34 c = ARCondition.new(@status == 0 ? "status <> 0" : ["status = ?", @status])
35 35
36 36 unless params[:name].blank?
37 37 name = "%#{params[:name].strip.downcase}%"
38 38 c << ["LOWER(login) LIKE ? OR LOWER(firstname) LIKE ? OR LOWER(lastname) LIKE ? OR LOWER(mail) LIKE ?", name, name, name, name]
39 39 end
40 40
41 41 @user_count = User.count(:conditions => c.conditions)
42 42 @user_pages = Paginator.new self, @user_count,
43 43 per_page_option,
44 44 params['page']
45 45 @users = User.find :all,:order => sort_clause,
46 46 :conditions => c.conditions,
47 47 :limit => @user_pages.items_per_page,
48 48 :offset => @user_pages.current.offset
49 49
50 50 respond_to do |format|
51 51 format.html { render :layout => !request.xhr? }
52 format.json { render :template => 'users/index.apit' }
53 format.xml { render :template => 'users/index.apit' }
52 format.api { render :template => 'users/index.apit' }
54 53 end
55 54 end
56 55
57 56 def show
58 57 @user = User.find(params[:id])
59 58
60 59 # show projects based on current user visibility
61 60 @memberships = @user.memberships.all(:conditions => Project.visible_by(User.current))
62 61
63 62 events = Redmine::Activity::Fetcher.new(User.current, :author => @user).events(nil, nil, :limit => 10)
64 63 @events_by_day = events.group_by(&:event_date)
65 64
66 65 unless User.current.admin?
67 66 if !@user.active? || (@user != User.current && @memberships.empty? && events.empty?)
68 67 render_404
69 68 return
70 69 end
71 70 end
72 71
73 72 respond_to do |format|
74 73 format.html { render :layout => 'base' }
75 format.json { render :template => 'users/show.apit' }
76 format.xml { render :template => 'users/show.apit' }
74 format.api { render :template => 'users/show.apit' }
77 75 end
78 76 rescue ActiveRecord::RecordNotFound
79 77 render_404
80 78 end
81 79
82 80 def new
83 81 @notification_options = User::MAIL_NOTIFICATION_OPTIONS
84 82 @notification_option = Setting.default_notification_option
85 83
86 84 @user = User.new(:language => Setting.default_language)
87 85 @auth_sources = AuthSource.find(:all)
88 86 end
89 87
90 88 verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
91 89 def create
92 90 @notification_options = User::MAIL_NOTIFICATION_OPTIONS
93 91 @notification_option = Setting.default_notification_option
94 92
95 93 @user = User.new(params[:user])
96 94 @user.admin = params[:user][:admin] || false
97 95 @user.login = params[:user][:login]
98 96 @user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless @user.auth_source_id
99 97
100 98 # TODO: Similar to My#account
101 99 @user.mail_notification = params[:notification_option] || 'only_my_events'
102 100 @user.pref.attributes = params[:pref]
103 101 @user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
104 102
105 103 if @user.save
106 104 @user.pref.save
107 105 @user.notified_project_ids = (params[:notification_option] == 'selected' ? params[:notified_project_ids] : [])
108 106
109 107 Mailer.deliver_account_information(@user, params[:password]) if params[:send_information]
110 108
111 109 respond_to do |format|
112 110 format.html {
113 111 flash[:notice] = l(:notice_successful_create)
114 112 redirect_to(params[:continue] ?
115 113 {:controller => 'users', :action => 'new'} :
116 114 {:controller => 'users', :action => 'edit', :id => @user}
117 115 )
118 116 }
119 format.json { render :template => 'users/show.apit', :status => :created, :location => user_url(@user) }
120 format.xml { render :template => 'users/show.apit', :status => :created, :location => user_url(@user) }
117 format.api { render :template => 'users/show.apit', :status => :created, :location => user_url(@user) }
121 118 end
122 119 else
123 120 @auth_sources = AuthSource.find(:all)
124 121 @notification_option = @user.mail_notification
125 122
126 123 respond_to do |format|
127 124 format.html { render :action => 'new' }
128 125 format.json { render :json => {:errors => @user.errors}, :status => :unprocessable_entity, :layout => false }
129 126 format.xml { render :xml => @user.errors, :status => :unprocessable_entity, :layout => false }
130 127 end
131 128 end
132 129 end
133 130
134 131 def edit
135 132 @user = User.find(params[:id])
136 133 @notification_options = @user.valid_notification_options
137 134 @notification_option = @user.mail_notification
138 135
139 136 @auth_sources = AuthSource.find(:all)
140 137 @membership ||= Member.new
141 138 end
142 139
143 140 verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
144 141 def update
145 142 @user = User.find(params[:id])
146 143 @notification_options = @user.valid_notification_options
147 144 @notification_option = @user.mail_notification
148 145
149 146 @user.admin = params[:user][:admin] if params[:user][:admin]
150 147 @user.login = params[:user][:login] if params[:user][:login]
151 148 if params[:password].present? && (@user.auth_source_id.nil? || params[:user][:auth_source_id].blank?)
152 149 @user.password, @user.password_confirmation = params[:password], params[:password_confirmation]
153 150 end
154 151 @user.group_ids = params[:user][:group_ids] if params[:user][:group_ids]
155 152 @user.attributes = params[:user]
156 153 # Was the account actived ? (do it before User#save clears the change)
157 154 was_activated = (@user.status_change == [User::STATUS_REGISTERED, User::STATUS_ACTIVE])
158 155 # TODO: Similar to My#account
159 156 @user.mail_notification = params[:notification_option] || 'only_my_events'
160 157 @user.pref.attributes = params[:pref]
161 158 @user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
162 159
163 160 if @user.save
164 161 @user.pref.save
165 162 @user.notified_project_ids = (params[:notification_option] == 'selected' ? params[:notified_project_ids] : [])
166 163
167 164 if was_activated
168 165 Mailer.deliver_account_activated(@user)
169 166 elsif @user.active? && params[:send_information] && !params[:password].blank? && @user.auth_source_id.nil?
170 167 Mailer.deliver_account_information(@user, params[:password])
171 168 end
172 169
173 170 respond_to do |format|
174 171 format.html {
175 172 flash[:notice] = l(:notice_successful_update)
176 173 redirect_to :back
177 174 }
178 format.json { head :ok }
179 format.xml { head :ok }
175 format.api { head :ok }
180 176 end
181 177 else
182 178 @auth_sources = AuthSource.find(:all)
183 179 @membership ||= Member.new
184 180
185 181 respond_to do |format|
186 182 format.html { render :action => :edit }
187 183 format.json { render :json => {:errors => @user.errors}, :status => :unprocessable_entity, :layout => false }
188 184 format.xml { render :xml => @user.errors, :status => :unprocessable_entity, :layout => false }
189 185 end
190 186 end
191 187 rescue ::ActionController::RedirectBackError
192 188 redirect_to :controller => 'users', :action => 'edit', :id => @user
193 189 end
194 190
195 191 def edit_membership
196 192 @user = User.find(params[:id])
197 193 @membership = Member.edit_membership(params[:membership_id], params[:membership], @user)
198 194 @membership.save if request.post?
199 195 respond_to do |format|
200 196 if @membership.valid?
201 197 format.html { redirect_to :controller => 'users', :action => 'edit', :id => @user, :tab => 'memberships' }
202 198 format.js {
203 199 render(:update) {|page|
204 200 page.replace_html "tab-content-memberships", :partial => 'users/memberships'
205 201 page.visual_effect(:highlight, "member-#{@membership.id}")
206 202 }
207 203 }
208 204 else
209 205 format.js {
210 206 render(:update) {|page|
211 207 page.alert(l(:notice_failed_to_save_members, :errors => @membership.errors.full_messages.join(', ')))
212 208 }
213 209 }
214 210 end
215 211 end
216 212 end
217 213
218 214 def destroy_membership
219 215 @user = User.find(params[:id])
220 216 @membership = Member.find(params[:membership_id])
221 217 if request.post? && @membership.deletable?
222 218 @membership.destroy
223 219 end
224 220 respond_to do |format|
225 221 format.html { redirect_to :controller => 'users', :action => 'edit', :id => @user, :tab => 'memberships' }
226 222 format.js { render(:update) {|page| page.replace_html "tab-content-memberships", :partial => 'users/memberships'} }
227 223 end
228 224 end
229 225 end
@@ -1,94 +1,104
1 1
2 2 require 'active_record'
3 3
4 4 module ActiveRecord
5 5 class Base
6 6 include Redmine::I18n
7 7
8 8 # Translate attribute names for validation errors display
9 9 def self.human_attribute_name(attr)
10 10 l("field_#{attr.to_s.gsub(/_id$/, '')}")
11 11 end
12 12 end
13 13 end
14 14
15 15 module ActiveRecord
16 16 class Errors
17 17 def full_messages(options = {})
18 18 full_messages = []
19 19
20 20 @errors.each_key do |attr|
21 21 @errors[attr].each do |message|
22 22 next unless message
23 23
24 24 if attr == "base"
25 25 full_messages << message
26 26 elsif attr == "custom_values"
27 27 # Replace the generic "custom values is invalid"
28 28 # with the errors on custom values
29 29 @base.custom_values.each do |value|
30 30 value.errors.each do |attr, msg|
31 31 full_messages << value.custom_field.name + ' ' + msg
32 32 end
33 33 end
34 34 else
35 35 attr_name = @base.class.human_attribute_name(attr)
36 36 full_messages << attr_name + ' ' + message.to_s
37 37 end
38 38 end
39 39 end
40 40 full_messages
41 41 end
42 42 end
43 43 end
44 44
45 45 module ActionView
46 46 module Helpers
47 47 module DateHelper
48 48 # distance_of_time_in_words breaks when difference is greater than 30 years
49 49 def distance_of_date_in_words(from_date, to_date = 0, options = {})
50 50 from_date = from_date.to_date if from_date.respond_to?(:to_date)
51 51 to_date = to_date.to_date if to_date.respond_to?(:to_date)
52 52 distance_in_days = (to_date - from_date).abs
53 53
54 54 I18n.with_options :locale => options[:locale], :scope => :'datetime.distance_in_words' do |locale|
55 55 case distance_in_days
56 56 when 0..60 then locale.t :x_days, :count => distance_in_days.round
57 57 when 61..720 then locale.t :about_x_months, :count => (distance_in_days / 30).round
58 58 else locale.t :over_x_years, :count => (distance_in_days / 365).floor
59 59 end
60 60 end
61 61 end
62 62 end
63 63 end
64 64 end
65 65
66 66 ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "#{html_tag}" }
67 67
68 68 # Adds :async_smtp and :async_sendmail delivery methods
69 69 # to perform email deliveries asynchronously
70 70 module AsynchronousMailer
71 71 %w(smtp sendmail).each do |type|
72 72 define_method("perform_delivery_async_#{type}") do |mail|
73 73 Thread.start do
74 74 send "perform_delivery_#{type}", mail
75 75 end
76 76 end
77 77 end
78 78 end
79 79
80 80 ActionMailer::Base.send :include, AsynchronousMailer
81 81
82 82 # TODO: Hack to support i18n 4.x on Rails 2.3.5. Remove post 2.3.6.
83 83 # See http://www.redmine.org/issues/6428 and http://www.redmine.org/issues/5608
84 84 module I18n
85 85 module Backend
86 86 module Base
87 87 def warn_syntax_deprecation!(*args)
88 88 return if @skip_syntax_deprecation
89 89 warn "The {{key}} interpolation syntax in I18n messages is deprecated. Please use %{key} instead.\nDowngrade your i18n gem to 0.3.7 (everything above must be deinstalled) to remove this warning, see http://www.redmine.org/issues/5608 for more information."
90 90 @skip_syntax_deprecation = true
91 91 end
92 92 end
93 93 end
94 94 end
95
96 module ActionController
97 module MimeResponds
98 class Responder
99 def api(&block)
100 any(:xml, :json, &block)
101 end
102 end
103 end
104 end
General Comments 0
You need to be logged in to leave comments. Login now