##// END OF EJS Templates
Refactor: Change the different find_object filters to share a common method....
Eric Davis -
r3483:194dab8e96f6
parent child
Show More
@@ -1,318 +1,332
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 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 require 'uri'
19 19 require 'cgi'
20 20
21 21 class ApplicationController < ActionController::Base
22 22 include Redmine::I18n
23 23
24 24 layout 'base'
25 25 exempt_from_layout 'builder'
26 26
27 27 # Remove broken cookie after upgrade from 0.8.x (#4292)
28 28 # See https://rails.lighthouseapp.com/projects/8994/tickets/3360
29 29 # TODO: remove it when Rails is fixed
30 30 before_filter :delete_broken_cookies
31 31 def delete_broken_cookies
32 32 if cookies['_redmine_session'] && cookies['_redmine_session'] !~ /--/
33 33 cookies.delete '_redmine_session'
34 34 redirect_to home_path
35 35 return false
36 36 end
37 37 end
38 38
39 39 before_filter :user_setup, :check_if_login_required, :set_localization
40 40 filter_parameter_logging :password
41 41 protect_from_forgery
42 42
43 43 rescue_from ActionController::InvalidAuthenticityToken, :with => :invalid_authenticity_token
44 44
45 45 include Redmine::Search::Controller
46 46 include Redmine::MenuManager::MenuController
47 47 helper Redmine::MenuManager::MenuHelper
48 48
49 49 Redmine::Scm::Base.all.each do |scm|
50 50 require_dependency "repository/#{scm.underscore}"
51 51 end
52 52
53 53 def user_setup
54 54 # Check the settings cache for each request
55 55 Setting.check_cache
56 56 # Find the current user
57 57 User.current = find_current_user
58 58 end
59 59
60 60 # Returns the current user or nil if no user is logged in
61 61 # and starts a session if needed
62 62 def find_current_user
63 63 if session[:user_id]
64 64 # existing session
65 65 (User.active.find(session[:user_id]) rescue nil)
66 66 elsif cookies[:autologin] && Setting.autologin?
67 67 # auto-login feature starts a new session
68 68 user = User.try_to_autologin(cookies[:autologin])
69 69 session[:user_id] = user.id if user
70 70 user
71 71 elsif params[:format] == 'atom' && params[:key] && accept_key_auth_actions.include?(params[:action])
72 72 # RSS key authentication does not start a session
73 73 User.find_by_rss_key(params[:key])
74 74 elsif Setting.rest_api_enabled? && ['xml', 'json'].include?(params[:format])
75 75 if params[:key].present? && accept_key_auth_actions.include?(params[:action])
76 76 # Use API key
77 77 User.find_by_api_key(params[:key])
78 78 else
79 79 # HTTP Basic, either username/password or API key/random
80 80 authenticate_with_http_basic do |username, password|
81 81 User.try_to_login(username, password) || User.find_by_api_key(username)
82 82 end
83 83 end
84 84 end
85 85 end
86 86
87 87 # Sets the logged in user
88 88 def logged_user=(user)
89 89 reset_session
90 90 if user && user.is_a?(User)
91 91 User.current = user
92 92 session[:user_id] = user.id
93 93 else
94 94 User.current = User.anonymous
95 95 end
96 96 end
97 97
98 98 # check if login is globally required to access the application
99 99 def check_if_login_required
100 100 # no check needed if user is already logged in
101 101 return true if User.current.logged?
102 102 require_login if Setting.login_required?
103 103 end
104 104
105 105 def set_localization
106 106 lang = nil
107 107 if User.current.logged?
108 108 lang = find_language(User.current.language)
109 109 end
110 110 if lang.nil? && request.env['HTTP_ACCEPT_LANGUAGE']
111 111 accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.downcase
112 112 if !accept_lang.blank?
113 113 lang = find_language(accept_lang) || find_language(accept_lang.split('-').first)
114 114 end
115 115 end
116 116 lang ||= Setting.default_language
117 117 set_language_if_valid(lang)
118 118 end
119 119
120 120 def require_login
121 121 if !User.current.logged?
122 122 # Extract only the basic url parameters on non-GET requests
123 123 if request.get?
124 124 url = url_for(params)
125 125 else
126 126 url = url_for(:controller => params[:controller], :action => params[:action], :id => params[:id], :project_id => params[:project_id])
127 127 end
128 128 respond_to do |format|
129 129 format.html { redirect_to :controller => "account", :action => "login", :back_url => url }
130 130 format.atom { redirect_to :controller => "account", :action => "login", :back_url => url }
131 131 format.xml { head :unauthorized }
132 132 format.json { head :unauthorized }
133 133 end
134 134 return false
135 135 end
136 136 true
137 137 end
138 138
139 139 def require_admin
140 140 return unless require_login
141 141 if !User.current.admin?
142 142 render_403
143 143 return false
144 144 end
145 145 true
146 146 end
147 147
148 148 def deny_access
149 149 User.current.logged? ? render_403 : require_login
150 150 end
151 151
152 152 # Authorize the user for the requested action
153 153 def authorize(ctrl = params[:controller], action = params[:action], global = false)
154 154 allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project, :global => global)
155 155 allowed ? true : deny_access
156 156 end
157 157
158 158 # Authorize the user for the requested action outside a project
159 159 def authorize_global(ctrl = params[:controller], action = params[:action], global = true)
160 160 authorize(ctrl, action, global)
161 161 end
162 162
163 163 # Find project of id params[:id]
164 164 def find_project
165 165 @project = Project.find(params[:id])
166 166 rescue ActiveRecord::RecordNotFound
167 167 render_404
168 168 end
169 169
170 170 # Finds and sets @project based on @object.project
171 171 def find_project_from_association
172 172 render_404 unless @object.present?
173 173
174 174 @project = @object.project
175 175 rescue ActiveRecord::RecordNotFound
176 176 render_404
177 177 end
178 178
179 def find_model_object
180 model = self.class.read_inheritable_attribute('model_object')
181 if model
182 @object = model.find(params[:id])
183 self.instance_variable_set('@' + controller_name.singularize, @object) if @object
184 end
185 rescue ActiveRecord::RecordNotFound
186 render_404
187 end
188
189 def self.model_object(model)
190 write_inheritable_attribute('model_object', model)
191 end
192
179 193 # make sure that the user is a member of the project (or admin) if project is private
180 194 # used as a before_filter for actions that do not require any particular permission on the project
181 195 def check_project_privacy
182 196 if @project && @project.active?
183 197 if @project.is_public? || User.current.member_of?(@project) || User.current.admin?
184 198 true
185 199 else
186 200 User.current.logged? ? render_403 : require_login
187 201 end
188 202 else
189 203 @project = nil
190 204 render_404
191 205 false
192 206 end
193 207 end
194 208
195 209 def redirect_back_or_default(default)
196 210 back_url = CGI.unescape(params[:back_url].to_s)
197 211 if !back_url.blank?
198 212 begin
199 213 uri = URI.parse(back_url)
200 214 # do not redirect user to another host or to the login or register page
201 215 if (uri.relative? || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)})
202 216 redirect_to(back_url)
203 217 return
204 218 end
205 219 rescue URI::InvalidURIError
206 220 # redirect to default
207 221 end
208 222 end
209 223 redirect_to default
210 224 end
211 225
212 226 def render_403
213 227 @project = nil
214 228 respond_to do |format|
215 229 format.html { render :template => "common/403", :layout => (request.xhr? ? false : 'base'), :status => 403 }
216 230 format.atom { head 403 }
217 231 format.xml { head 403 }
218 232 format.json { head 403 }
219 233 end
220 234 return false
221 235 end
222 236
223 237 def render_404
224 238 respond_to do |format|
225 239 format.html { render :template => "common/404", :layout => !request.xhr?, :status => 404 }
226 240 format.atom { head 404 }
227 241 format.xml { head 404 }
228 242 format.json { head 404 }
229 243 end
230 244 return false
231 245 end
232 246
233 247 def render_error(msg)
234 248 respond_to do |format|
235 249 format.html {
236 250 flash.now[:error] = msg
237 251 render :text => '', :layout => !request.xhr?, :status => 500
238 252 }
239 253 format.atom { head 500 }
240 254 format.xml { head 500 }
241 255 format.json { head 500 }
242 256 end
243 257 end
244 258
245 259 def invalid_authenticity_token
246 260 if api_request?
247 261 logger.error "Form authenticity token is missing or is invalid. API calls must include a proper Content-type header (text/xml or text/json)."
248 262 end
249 263 render_error "Invalid form authenticity token."
250 264 end
251 265
252 266 def render_feed(items, options={})
253 267 @items = items || []
254 268 @items.sort! {|x,y| y.event_datetime <=> x.event_datetime }
255 269 @items = @items.slice(0, Setting.feeds_limit.to_i)
256 270 @title = options[:title] || Setting.app_title
257 271 render :template => "common/feed.atom.rxml", :layout => false, :content_type => 'application/atom+xml'
258 272 end
259 273
260 274 def self.accept_key_auth(*actions)
261 275 actions = actions.flatten.map(&:to_s)
262 276 write_inheritable_attribute('accept_key_auth_actions', actions)
263 277 end
264 278
265 279 def accept_key_auth_actions
266 280 self.class.read_inheritable_attribute('accept_key_auth_actions') || []
267 281 end
268 282
269 283 # Returns the number of objects that should be displayed
270 284 # on the paginated list
271 285 def per_page_option
272 286 per_page = nil
273 287 if params[:per_page] && Setting.per_page_options_array.include?(params[:per_page].to_s.to_i)
274 288 per_page = params[:per_page].to_s.to_i
275 289 session[:per_page] = per_page
276 290 elsif session[:per_page]
277 291 per_page = session[:per_page]
278 292 else
279 293 per_page = Setting.per_page_options_array.first || 25
280 294 end
281 295 per_page
282 296 end
283 297
284 298 # qvalues http header parser
285 299 # code taken from webrick
286 300 def parse_qvalues(value)
287 301 tmp = []
288 302 if value
289 303 parts = value.split(/,\s*/)
290 304 parts.each {|part|
291 305 if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
292 306 val = m[1]
293 307 q = (m[2] or 1).to_f
294 308 tmp.push([val, q])
295 309 end
296 310 }
297 311 tmp = tmp.sort_by{|val, q| -q}
298 312 tmp.collect!{|val, q| val}
299 313 end
300 314 return tmp
301 315 rescue
302 316 nil
303 317 end
304 318
305 319 # Returns a string that can be used as filename value in Content-Disposition header
306 320 def filename_for_content_disposition(name)
307 321 request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(name) : name
308 322 end
309 323
310 324 def api_request?
311 325 %w(xml json).include? params[:format]
312 326 end
313 327
314 328 # Renders a warning flash if obj has unsaved attachments
315 329 def render_attachment_warning_if_needed(obj)
316 330 flash[:warning] = l(:warning_attachments_not_saved, obj.unsaved_attachments.size) if obj.unsaved_attachments.present?
317 331 end
318 332 end
@@ -1,91 +1,86
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 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 DocumentsController < ApplicationController
19 19 default_search_scope :documents
20 model_object Document
20 21 before_filter :find_project, :only => [:index, :new]
21 before_filter :find_document, :except => [:index, :new]
22 before_filter :find_model_object, :except => [:index, :new]
22 23 before_filter :find_project_from_association, :except => [:index, :new]
23 24 before_filter :authorize
24 25
25 26 helper :attachments
26 27
27 28 def index
28 29 @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
29 30 documents = @project.documents.find :all, :include => [:attachments, :category]
30 31 case @sort_by
31 32 when 'date'
32 33 @grouped = documents.group_by {|d| d.updated_on.to_date }
33 34 when 'title'
34 35 @grouped = documents.group_by {|d| d.title.first.upcase}
35 36 when 'author'
36 37 @grouped = documents.select{|d| d.attachments.any?}.group_by {|d| d.attachments.last.author}
37 38 else
38 39 @grouped = documents.group_by(&:category)
39 40 end
40 41 @document = @project.documents.build
41 42 render :layout => false if request.xhr?
42 43 end
43 44
44 45 def show
45 46 @attachments = @document.attachments.find(:all, :order => "created_on DESC")
46 47 end
47 48
48 49 def new
49 50 @document = @project.documents.build(params[:document])
50 51 if request.post? and @document.save
51 52 attachments = Attachment.attach_files(@document, params[:attachments])
52 53 render_attachment_warning_if_needed(@document)
53 54 flash[:notice] = l(:notice_successful_create)
54 55 redirect_to :action => 'index', :project_id => @project
55 56 end
56 57 end
57 58
58 59 def edit
59 60 @categories = DocumentCategory.all
60 61 if request.post? and @document.update_attributes(params[:document])
61 62 flash[:notice] = l(:notice_successful_update)
62 63 redirect_to :action => 'show', :id => @document
63 64 end
64 65 end
65 66
66 67 def destroy
67 68 @document.destroy
68 69 redirect_to :controller => 'documents', :action => 'index', :project_id => @project
69 70 end
70 71
71 72 def add_attachment
72 73 attachments = Attachment.attach_files(@document, params[:attachments])
73 74 render_attachment_warning_if_needed(@document)
74 75
75 76 Mailer.deliver_attachments_added(attachments[:files]) if attachments.present? && attachments[:files].present? && Setting.notified_events.include?('document_added')
76 77 redirect_to :action => 'show', :id => @document
77 78 end
78 79
79 80 private
80 81 def find_project
81 82 @project = Project.find(params[:project_id])
82 83 rescue ActiveRecord::RecordNotFound
83 84 render_404
84 85 end
85
86 def find_document
87 @document = @object = Document.find(params[:id])
88 rescue ActiveRecord::RecordNotFound
89 render_404
90 end
91 86 end
@@ -1,87 +1,89
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 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 IssueCategoriesController < ApplicationController
19 19 menu_item :settings
20 before_filter :find_category, :except => :new
20 model_object IssueCategory
21 before_filter :find_model_object, :except => :new
21 22 before_filter :find_project_from_association, :except => :new
22 23 before_filter :find_project, :only => :new
23 24 before_filter :authorize
24 25
25 26 verify :method => :post, :only => :destroy
26 27
27 28 def new
28 29 @category = @project.issue_categories.build(params[:category])
29 30 if request.post?
30 31 if @category.save
31 32 respond_to do |format|
32 33 format.html do
33 34 flash[:notice] = l(:notice_successful_create)
34 35 redirect_to :controller => 'projects', :action => 'settings', :tab => 'categories', :id => @project
35 36 end
36 37 format.js do
37 38 # IE doesn't support the replace_html rjs method for select box options
38 39 render(:update) {|page| page.replace "issue_category_id",
39 40 content_tag('select', '<option></option>' + options_from_collection_for_select(@project.issue_categories, 'id', 'name', @category.id), :id => 'issue_category_id', :name => 'issue[category_id]')
40 41 }
41 42 end
42 43 end
43 44 else
44 45 respond_to do |format|
45 46 format.html
46 47 format.js do
47 48 render(:update) {|page| page.alert(@category.errors.full_messages.join('\n')) }
48 49 end
49 50 end
50 51 end
51 52 end
52 53 end
53 54
54 55 def edit
55 56 if request.post? and @category.update_attributes(params[:category])
56 57 flash[:notice] = l(:notice_successful_update)
57 58 redirect_to :controller => 'projects', :action => 'settings', :tab => 'categories', :id => @project
58 59 end
59 60 end
60 61
61 62 def destroy
62 63 @issue_count = @category.issues.size
63 64 if @issue_count == 0
64 65 # No issue assigned to this category
65 66 @category.destroy
66 67 redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'categories'
67 68 elsif params[:todo]
68 69 reassign_to = @project.issue_categories.find_by_id(params[:reassign_to_id]) if params[:todo] == 'reassign'
69 70 @category.destroy(reassign_to)
70 71 redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'categories'
71 72 end
72 73 @categories = @project.issue_categories - [@category]
73 74 end
74 75
75 76 private
76 def find_category
77 @category = @object = IssueCategory.find(params[:id])
78 rescue ActiveRecord::RecordNotFound
79 render_404
77 # Wrap ApplicationController's find_model_object method to set
78 # @category instead of just @issue_category
79 def find_model_object
80 super
81 @category = @object
80 82 end
81 83
82 84 def find_project
83 85 @project = Project.find(params[:project_id])
84 86 rescue ActiveRecord::RecordNotFound
85 87 render_404
86 88 end
87 89 end
@@ -1,83 +1,78
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 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 MembersController < ApplicationController
19 before_filter :find_member, :except => [:new, :autocomplete_for_member]
19 model_object Member
20 before_filter :find_model_object, :except => [:new, :autocomplete_for_member]
20 21 before_filter :find_project_from_association, :except => [:new, :autocomplete_for_member]
21 22 before_filter :find_project, :only => [:new, :autocomplete_for_member]
22 23 before_filter :authorize
23 24
24 25 def new
25 26 members = []
26 27 if params[:member] && request.post?
27 28 attrs = params[:member].dup
28 29 if (user_ids = attrs.delete(:user_ids))
29 30 user_ids.each do |user_id|
30 31 members << Member.new(attrs.merge(:user_id => user_id))
31 32 end
32 33 else
33 34 members << Member.new(attrs)
34 35 end
35 36 @project.members << members
36 37 end
37 38 respond_to do |format|
38 39 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
39 40 format.js {
40 41 render(:update) {|page|
41 42 page.replace_html "tab-content-members", :partial => 'projects/settings/members'
42 43 members.each {|member| page.visual_effect(:highlight, "member-#{member.id}") }
43 44 }
44 45 }
45 46 end
46 47 end
47 48
48 49 def edit
49 50 if request.post? and @member.update_attributes(params[:member])
50 51 respond_to do |format|
51 52 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
52 53 format.js {
53 54 render(:update) {|page|
54 55 page.replace_html "tab-content-members", :partial => 'projects/settings/members'
55 56 page.visual_effect(:highlight, "member-#{@member.id}")
56 57 }
57 58 }
58 59 end
59 60 end
60 61 end
61 62
62 63 def destroy
63 64 if request.post? && @member.deletable?
64 65 @member.destroy
65 66 end
66 67 respond_to do |format|
67 68 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
68 69 format.js { render(:update) {|page| page.replace_html "tab-content-members", :partial => 'projects/settings/members'} }
69 70 end
70 71 end
71 72
72 73 def autocomplete_for_member
73 74 @principals = Principal.active.like(params[:q]).find(:all, :limit => 100) - @project.principals
74 75 render :layout => false
75 76 end
76 77
77 private
78 def find_member
79 @member = @object = Member.find(params[:id])
80 rescue ActiveRecord::RecordNotFound
81 render_404
82 end
83 78 end
@@ -1,111 +1,106
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 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 NewsController < ApplicationController
19 19 default_search_scope :news
20 before_filter :find_news, :except => [:new, :index, :preview]
20 model_object News
21 before_filter :find_model_object, :except => [:new, :index, :preview]
21 22 before_filter :find_project_from_association, :except => [:new, :index, :preview]
22 23 before_filter :find_project, :only => [:new, :preview]
23 24 before_filter :authorize, :except => [:index, :preview]
24 25 before_filter :find_optional_project, :only => :index
25 26 accept_key_auth :index
26 27
27 28 def index
28 29 @news_pages, @newss = paginate :news,
29 30 :per_page => 10,
30 31 :conditions => Project.allowed_to_condition(User.current, :view_news, :project => @project),
31 32 :include => [:author, :project],
32 33 :order => "#{News.table_name}.created_on DESC"
33 34 respond_to do |format|
34 35 format.html { render :layout => false if request.xhr? }
35 36 format.xml { render :xml => @newss.to_xml }
36 37 format.json { render :json => @newss.to_json }
37 38 format.atom { render_feed(@newss, :title => (@project ? @project.name : Setting.app_title) + ": #{l(:label_news_plural)}") }
38 39 end
39 40 end
40 41
41 42 def show
42 43 @comments = @news.comments
43 44 @comments.reverse! if User.current.wants_comments_in_reverse_order?
44 45 end
45 46
46 47 def new
47 48 @news = News.new(:project => @project, :author => User.current)
48 49 if request.post?
49 50 @news.attributes = params[:news]
50 51 if @news.save
51 52 flash[:notice] = l(:notice_successful_create)
52 53 redirect_to :controller => 'news', :action => 'index', :project_id => @project
53 54 end
54 55 end
55 56 end
56 57
57 58 def edit
58 59 if request.post? and @news.update_attributes(params[:news])
59 60 flash[:notice] = l(:notice_successful_update)
60 61 redirect_to :action => 'show', :id => @news
61 62 end
62 63 end
63 64
64 65 def add_comment
65 66 @comment = Comment.new(params[:comment])
66 67 @comment.author = User.current
67 68 if @news.comments << @comment
68 69 flash[:notice] = l(:label_comment_added)
69 70 redirect_to :action => 'show', :id => @news
70 71 else
71 72 show
72 73 render :action => 'show'
73 74 end
74 75 end
75 76
76 77 def destroy_comment
77 78 @news.comments.find(params[:comment_id]).destroy
78 79 redirect_to :action => 'show', :id => @news
79 80 end
80 81
81 82 def destroy
82 83 @news.destroy
83 84 redirect_to :action => 'index', :project_id => @project
84 85 end
85 86
86 87 def preview
87 88 @text = (params[:news] ? params[:news][:description] : nil)
88 89 render :partial => 'common/preview'
89 90 end
90 91
91 92 private
92 def find_news
93 @news = @object = News.find(params[:id])
94 rescue ActiveRecord::RecordNotFound
95 render_404
96 end
97
98 93 def find_project
99 94 @project = Project.find(params[:project_id])
100 95 rescue ActiveRecord::RecordNotFound
101 96 render_404
102 97 end
103 98
104 99 def find_optional_project
105 100 return true unless params[:project_id]
106 101 @project = Project.find(params[:project_id])
107 102 authorize
108 103 rescue ActiveRecord::RecordNotFound
109 104 render_404
110 105 end
111 106 end
@@ -1,108 +1,103
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 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 VersionsController < ApplicationController
19 19 menu_item :roadmap
20 before_filter :find_version, :except => [:new, :close_completed]
20 model_object Version
21 before_filter :find_model_object, :except => [:new, :close_completed]
21 22 before_filter :find_project_from_association, :except => [:new, :close_completed]
22 23 before_filter :find_project, :only => [:new, :close_completed]
23 24 before_filter :authorize
24 25
25 26 helper :custom_fields
26 27 helper :projects
27 28
28 29 def show
29 30 end
30 31
31 32 def new
32 33 @version = @project.versions.build
33 34 if params[:version]
34 35 attributes = params[:version].dup
35 36 attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing'])
36 37 @version.attributes = attributes
37 38 end
38 39 if request.post?
39 40 if @version.save
40 41 respond_to do |format|
41 42 format.html do
42 43 flash[:notice] = l(:notice_successful_create)
43 44 redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
44 45 end
45 46 format.js do
46 47 # IE doesn't support the replace_html rjs method for select box options
47 48 render(:update) {|page| page.replace "issue_fixed_version_id",
48 49 content_tag('select', '<option></option>' + version_options_for_select(@project.shared_versions.open, @version), :id => 'issue_fixed_version_id', :name => 'issue[fixed_version_id]')
49 50 }
50 51 end
51 52 end
52 53 else
53 54 respond_to do |format|
54 55 format.html
55 56 format.js do
56 57 render(:update) {|page| page.alert(@version.errors.full_messages.join('\n')) }
57 58 end
58 59 end
59 60 end
60 61 end
61 62 end
62 63
63 64 def edit
64 65 if request.post? && params[:version]
65 66 attributes = params[:version].dup
66 67 attributes.delete('sharing') unless @version.allowed_sharings.include?(attributes['sharing'])
67 68 if @version.update_attributes(attributes)
68 69 flash[:notice] = l(:notice_successful_update)
69 70 redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
70 71 end
71 72 end
72 73 end
73 74
74 75 def close_completed
75 76 if request.post?
76 77 @project.close_completed_versions
77 78 end
78 79 redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
79 80 end
80 81
81 82 def destroy
82 83 @version.destroy
83 84 redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
84 85 rescue
85 86 flash[:error] = l(:notice_unable_delete_version)
86 87 redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
87 88 end
88 89
89 90 def status_by
90 91 respond_to do |format|
91 92 format.html { render :action => 'show' }
92 93 format.js { render(:update) {|page| page.replace_html 'status_by', render_issue_status_by(@version, params[:status_by])} }
93 94 end
94 95 end
95 96
96 97 private
97 def find_version
98 @version = @object = Version.find(params[:id])
99 rescue ActiveRecord::RecordNotFound
100 render_404
101 end
102
103 98 def find_project
104 99 @project = Project.find(params[:project_id])
105 100 rescue ActiveRecord::RecordNotFound
106 101 render_404
107 102 end
108 103 end
General Comments 0
You need to be logged in to leave comments. Login now