comparison app/controllers/wiki_controller.rb @ 1115:433d4f72a19b redmine-2.2

Update to Redmine SVN revision 11137 on 2.2-stable branch
author Chris Cannam
date Mon, 07 Jan 2013 12:01:42 +0000
parents cbb26bc654de
children 622f24f53b42 261b3d9a4903
comparison
equal deleted inserted replaced
929:5f33065ddc4b 1115:433d4f72a19b
1 # Redmine - project management software 1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang 2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 # 3 #
4 # This program is free software; you can redistribute it and/or 4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License 5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2 6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version. 7 # of the License, or (at your option) any later version.
33 # TODO: still being worked on 33 # TODO: still being worked on
34 class WikiController < ApplicationController 34 class WikiController < ApplicationController
35 default_search_scope :wiki_pages 35 default_search_scope :wiki_pages
36 before_filter :find_wiki, :authorize 36 before_filter :find_wiki, :authorize
37 before_filter :find_existing_or_new_page, :only => [:show, :edit, :update] 37 before_filter :find_existing_or_new_page, :only => [:show, :edit, :update]
38 before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy] 38 before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy, :destroy_version]
39 accept_api_auth :index, :show, :update, :destroy
39 40
40 helper :attachments 41 helper :attachments
41 include AttachmentsHelper 42 include AttachmentsHelper
42 helper :watchers 43 helper :watchers
43 include Redmine::Export::PDF 44 include Redmine::Export::PDF
44 45
45 # List of pages, sorted alphabetically and by parent (hierarchy) 46 # List of pages, sorted alphabetically and by parent (hierarchy)
46 def index 47 def index
47 load_pages_for_index 48 load_pages_for_index
48 @pages_by_parent_id = @pages.group_by(&:parent_id) 49
50 respond_to do |format|
51 format.html {
52 @pages_by_parent_id = @pages.group_by(&:parent_id)
53 }
54 format.api
55 end
49 end 56 end
50 57
51 # List of page, by last update 58 # List of page, by last update
52 def date_index 59 def date_index
53 load_pages_for_index 60 load_pages_for_index
55 end 62 end
56 63
57 # display a page (in editing mode if it doesn't exist) 64 # display a page (in editing mode if it doesn't exist)
58 def show 65 def show
59 if @page.new_record? 66 if @page.new_record?
60 if User.current.allowed_to?(:edit_wiki_pages, @project) && editable? 67 if User.current.allowed_to?(:edit_wiki_pages, @project) && editable? && !api_request?
61 edit 68 edit
62 render :action => 'edit' 69 render :action => 'edit'
63 else 70 else
64 render_404 71 render_404
65 end 72 end
66 return 73 return
67 end 74 end
68 if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project) 75 if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
69 # Redirects user to the current version if he's not allowed to view previous versions 76 deny_access
70 redirect_to :version => nil
71 return 77 return
72 end 78 end
73 @content = @page.content_for_version(params[:version]) 79 @content = @page.content_for_version(params[:version])
74 if User.current.allowed_to?(:export_wiki_pages, @project) 80 if User.current.allowed_to?(:export_wiki_pages, @project)
75 if params[:format] == 'pdf' 81 if params[:format] == 'pdf'
76 send_data(wiki_to_pdf(@page, @project), :type => 'application/pdf', :filename => "#{@page.title}.pdf") 82 send_data(wiki_page_to_pdf(@page, @project), :type => 'application/pdf', :filename => "#{@page.title}.pdf")
77 return 83 return
78 elsif params[:format] == 'html' 84 elsif params[:format] == 'html'
79 export = render_to_string :action => 'export', :layout => false 85 export = render_to_string :action => 'export', :layout => false
80 send_data(export, :type => 'text/html', :filename => "#{@page.title}.html") 86 send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
81 return 87 return
87 @editable = editable? 93 @editable = editable?
88 @sections_editable = @editable && User.current.allowed_to?(:edit_wiki_pages, @page.project) && 94 @sections_editable = @editable && User.current.allowed_to?(:edit_wiki_pages, @page.project) &&
89 @content.current_version? && 95 @content.current_version? &&
90 Redmine::WikiFormatting.supports_section_edit? 96 Redmine::WikiFormatting.supports_section_edit?
91 97
92 render :action => 'show' 98 respond_to do |format|
99 format.html
100 format.api
101 end
93 end 102 end
94 103
95 # edit an existing page or a new one 104 # edit an existing page or a new one
96 def edit 105 def edit
97 return render_403 unless editable? 106 return render_403 unless editable?
98 @page.content = WikiContent.new(:page => @page) if @page.new_record? 107 if @page.new_record?
108 @page.content = WikiContent.new(:page => @page)
109 if params[:parent].present?
110 @page.parent = @page.wiki.find_page(params[:parent].to_s)
111 end
112 end
99 113
100 @content = @page.content_for_version(params[:version]) 114 @content = @page.content_for_version(params[:version])
101 @content.text = initial_page_content(@page) if @content.text.blank? 115 @content.text = initial_page_content(@page) if @content.text.blank?
102 # don't keep previous comment 116 # don't keep previous comment
103 @content.comments = nil 117 @content.comments = nil
104 118
105 # To prevent StaleObjectError exception when reverting to a previous version 119 # To prevent StaleObjectError exception when reverting to a previous version
106 @content.version = @page.content.version 120 @content.version = @page.content.version
107 121
108 @text = @content.text 122 @text = @content.text
109 if params[:section].present? && Redmine::WikiFormatting.supports_section_edit? 123 if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
110 @section = params[:section].to_i 124 @section = params[:section].to_i
111 @text, @section_hash = Redmine::WikiFormatting.formatter.new(@text).get_section(@section) 125 @text, @section_hash = Redmine::WikiFormatting.formatter.new(@text).get_section(@section)
112 render_404 if @text.blank? 126 render_404 if @text.blank?
113 end 127 end
114 end 128 end
115 129
116 verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
117 # Creates a new page or updates an existing one 130 # Creates a new page or updates an existing one
118 def update 131 def update
119 return render_403 unless editable? 132 return render_403 unless editable?
133 was_new_page = @page.new_record?
120 @page.content = WikiContent.new(:page => @page) if @page.new_record? 134 @page.content = WikiContent.new(:page => @page) if @page.new_record?
121 135 @page.safe_attributes = params[:wiki_page]
122 @content = @page.content_for_version(params[:version]) 136
123 @content.text = initial_page_content(@page) if @content.text.blank? 137 @content = @page.content
124 # don't keep previous comment 138 content_params = params[:content]
125 @content.comments = nil 139 if content_params.nil? && params[:wiki_page].is_a?(Hash)
126 140 content_params = params[:wiki_page].slice(:text, :comments, :version)
127 if !@page.new_record? && params[:content].present? && @content.text == params[:content][:text] 141 end
128 attachments = Attachment.attach_files(@page, params[:attachments]) 142 content_params ||= {}
129 render_attachment_warning_if_needed(@page) 143
130 # don't save if text wasn't changed 144 @content.comments = content_params[:comments]
131 redirect_to :action => 'show', :project_id => @project, :id => @page.title 145 @text = content_params[:text]
132 return
133 end
134
135 @content.comments = params[:content][:comments]
136 @text = params[:content][:text]
137 if params[:section].present? && Redmine::WikiFormatting.supports_section_edit? 146 if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
138 @section = params[:section].to_i 147 @section = params[:section].to_i
139 @section_hash = params[:section_hash] 148 @section_hash = params[:section_hash]
140 @content.text = Redmine::WikiFormatting.formatter.new(@content.text).update_section(params[:section].to_i, @text, @section_hash) 149 @content.text = Redmine::WikiFormatting.formatter.new(@content.text).update_section(params[:section].to_i, @text, @section_hash)
141 else 150 else
142 @content.version = params[:content][:version] 151 @content.version = content_params[:version] if content_params[:version]
143 @content.text = @text 152 @content.text = @text
144 end 153 end
145 @content.author = User.current 154 @content.author = User.current
146 # if page is new @page.save will also save content, but not if page isn't a new record 155
147 if (@page.new_record? ? @page.save : @content.save) 156 if @page.save_with_content
148 attachments = Attachment.attach_files(@page, params[:attachments]) 157 attachments = Attachment.attach_files(@page, params[:attachments])
149 render_attachment_warning_if_needed(@page) 158 render_attachment_warning_if_needed(@page)
150 call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page}) 159 call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
151 redirect_to :action => 'show', :project_id => @project, :id => @page.title 160
161 respond_to do |format|
162 format.html { redirect_to :action => 'show', :project_id => @project, :id => @page.title }
163 format.api {
164 if was_new_page
165 render :action => 'show', :status => :created, :location => url_for(:controller => 'wiki', :action => 'show', :project_id => @project, :id => @page.title)
166 else
167 render_api_ok
168 end
169 }
170 end
152 else 171 else
153 render :action => 'edit' 172 respond_to do |format|
173 format.html { render :action => 'edit' }
174 format.api { render_validation_errors(@content) }
175 end
154 end 176 end
155 177
156 rescue ActiveRecord::StaleObjectError, Redmine::WikiFormatting::StaleSectionError 178 rescue ActiveRecord::StaleObjectError, Redmine::WikiFormatting::StaleSectionError
157 # Optimistic locking exception 179 # Optimistic locking exception
158 flash.now[:error] = l(:notice_locking_conflict) 180 respond_to do |format|
159 render :action => 'edit' 181 format.html {
182 flash.now[:error] = l(:notice_locking_conflict)
183 render :action => 'edit'
184 }
185 format.api { render_api_head :conflict }
186 end
187 rescue ActiveRecord::RecordNotSaved
188 respond_to do |format|
189 format.html { render :action => 'edit' }
190 format.api { render_validation_errors(@content) }
191 end
160 end 192 end
161 193
162 # rename a page 194 # rename a page
163 def rename 195 def rename
164 return render_403 unless editable? 196 return render_403 unless editable?
169 flash[:notice] = l(:notice_successful_update) 201 flash[:notice] = l(:notice_successful_update)
170 redirect_to :action => 'show', :project_id => @project, :id => @page.title 202 redirect_to :action => 'show', :project_id => @project, :id => @page.title
171 end 203 end
172 end 204 end
173 205
174 verify :method => :post, :only => :protect, :redirect_to => { :action => :show }
175 def protect 206 def protect
176 @page.update_attribute :protected, params[:protected] 207 @page.update_attribute :protected, params[:protected]
177 redirect_to :action => 'show', :project_id => @project, :id => @page.title 208 redirect_to :action => 'show', :project_id => @project, :id => @page.title
178 end 209 end
179 210
180 # show page history 211 # show page history
181 def history 212 def history
182 @version_count = @page.content.versions.count 213 @version_count = @page.content.versions.count
183 @version_pages = Paginator.new self, @version_count, per_page_option, params['p'] 214 @version_pages = Paginator.new self, @version_count, per_page_option, params['page']
184 # don't load text 215 # don't load text
185 @versions = @page.content.versions.find :all, 216 @versions = @page.content.versions.find :all,
186 :select => "id, author_id, comments, updated_on, version", 217 :select => "id, author_id, comments, updated_on, version",
187 :order => 'version DESC', 218 :order => 'version DESC',
188 :limit => @version_pages.items_per_page + 1, 219 :limit => @version_pages.items_per_page + 1,
199 def annotate 230 def annotate
200 @annotate = @page.annotate(params[:version]) 231 @annotate = @page.annotate(params[:version])
201 render_404 unless @annotate 232 render_404 unless @annotate
202 end 233 end
203 234
204 verify :method => :delete, :only => [:destroy], :redirect_to => { :action => :show }
205 # Removes a wiki page and its history 235 # Removes a wiki page and its history
206 # Children can be either set as root pages, removed or reassigned to another parent page 236 # Children can be either set as root pages, removed or reassigned to another parent page
207 def destroy 237 def destroy
208 return render_403 unless editable? 238 return render_403 unless editable?
209 239
222 @page.children.each do |child| 252 @page.children.each do |child|
223 child.update_attribute(:parent, reassign_to) 253 child.update_attribute(:parent, reassign_to)
224 end 254 end
225 else 255 else
226 @reassignable_to = @wiki.pages - @page.self_and_descendants 256 @reassignable_to = @wiki.pages - @page.self_and_descendants
227 return 257 # display the destroy form if it's a user request
258 return unless api_request?
228 end 259 end
229 end 260 end
230 @page.destroy 261 @page.destroy
231 redirect_to :action => 'index', :project_id => @project 262 respond_to do |format|
232 end 263 format.html { redirect_to :action => 'index', :project_id => @project }
233 264 format.api { render_api_ok }
234 # Export wiki to a single html file 265 end
266 end
267
268 def destroy_version
269 return render_403 unless editable?
270
271 @content = @page.content_for_version(params[:version])
272 @content.destroy
273 redirect_to_referer_or :action => 'history', :id => @page.title, :project_id => @project
274 end
275
276 # Export wiki to a single pdf or html file
235 def export 277 def export
236 if User.current.allowed_to?(:export_wiki_pages, @project) 278 @pages = @wiki.pages.all(:order => 'title', :include => [:content, {:attachments => :author}])
237 @pages = @wiki.pages.find :all, :order => 'title' 279 respond_to do |format|
238 export = render_to_string :action => 'export_multiple', :layout => false 280 format.html {
239 send_data(export, :type => 'text/html', :filename => "wiki.html") 281 export = render_to_string :action => 'export_multiple', :layout => false
240 else 282 send_data(export, :type => 'text/html', :filename => "wiki.html")
241 redirect_to :action => 'show', :project_id => @project, :id => nil 283 }
284 format.pdf {
285 send_data(wiki_pages_to_pdf(@pages, @project), :type => 'application/pdf', :filename => "#{@project.identifier}.pdf")
286 }
242 end 287 end
243 end 288 end
244 289
245 def preview 290 def preview
246 page = @wiki.find_page(params[:id]) 291 page = @wiki.find_page(params[:id])
302 extend helper unless self.instance_of?(helper) 347 extend helper unless self.instance_of?(helper)
303 helper.instance_method(:initial_page_content).bind(self).call(page) 348 helper.instance_method(:initial_page_content).bind(self).call(page)
304 end 349 end
305 350
306 def load_pages_for_index 351 def load_pages_for_index
307 @pages = @wiki.pages.with_updated_on.all(:order => 'title', :include => {:wiki => :project}) 352 @pages = @wiki.pages.with_updated_on.order("#{WikiPage.table_name}.title").includes(:wiki => :project).includes(:parent).all
308 end 353 end
309 end 354 end