comparison app/controllers/.svn/text-base/wiki_controller.rb.svn-base @ 37:94944d00e43c

* Update to SVN trunk rev 4411
author Chris Cannam <chris.cannam@soundsoftware.ac.uk>
date Fri, 19 Nov 2010 13:24:41 +0000
parents 513646585e45
children af80e5618e9b
comparison
equal deleted inserted replaced
22:40f7cfd4df19 37:94944d00e43c
15 # along with this program; if not, write to the Free Software 15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require 'diff' 18 require 'diff'
19 19
20 # The WikiController follows the Rails REST controller pattern but with
21 # a few differences
22 #
23 # * index - shows a list of WikiPages grouped by page or date
24 # * new - not used
25 # * create - not used
26 # * show - will also show the form for creating a new wiki page
27 # * edit - used to edit an existing or new page
28 # * update - used to save a wiki page update to the database, including new pages
29 # * destroy - normal
30 #
31 # Other member and collection methods are also used
32 #
33 # TODO: still being worked on
20 class WikiController < ApplicationController 34 class WikiController < ApplicationController
21 default_search_scope :wiki_pages 35 default_search_scope :wiki_pages
22 before_filter :find_wiki, :authorize 36 before_filter :find_wiki, :authorize
23 before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy] 37 before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy]
24 38
25 verify :method => :post, :only => [:destroy, :protect], :redirect_to => { :action => :index } 39 verify :method => :post, :only => [:protect], :redirect_to => { :action => :show }
26 40
27 helper :attachments 41 helper :attachments
28 include AttachmentsHelper 42 include AttachmentsHelper
29 helper :watchers 43 helper :watchers
30 44
45 # List of pages, sorted alphabetically and by parent (hierarchy)
46 def index
47 load_pages_grouped_by_date_without_content
48 end
49
31 # display a page (in editing mode if it doesn't exist) 50 # display a page (in editing mode if it doesn't exist)
32 def index 51 def show
33 page_title = params[:page] 52 page_title = params[:id]
34 @page = @wiki.find_or_new_page(page_title) 53 @page = @wiki.find_or_new_page(page_title)
35 if @page.new_record? 54 if @page.new_record?
36 if User.current.allowed_to?(:edit_wiki_pages, @project) && editable? 55 if User.current.allowed_to?(:edit_wiki_pages, @project) && editable?
37 edit 56 edit
38 render :action => 'edit' 57 render :action => 'edit'
61 render :action => 'show' 80 render :action => 'show'
62 end 81 end
63 82
64 # edit an existing page or a new one 83 # edit an existing page or a new one
65 def edit 84 def edit
66 @page = @wiki.find_or_new_page(params[:page]) 85 @page = @wiki.find_or_new_page(params[:id])
67 return render_403 unless editable? 86 return render_403 unless editable?
68 @page.content = WikiContent.new(:page => @page) if @page.new_record? 87 @page.content = WikiContent.new(:page => @page) if @page.new_record?
69 88
70 @content = @page.content_for_version(params[:version]) 89 @content = @page.content_for_version(params[:version])
71 @content.text = initial_page_content(@page) if @content.text.blank? 90 @content.text = initial_page_content(@page) if @content.text.blank?
72 # don't keep previous comment 91 # don't keep previous comment
73 @content.comments = nil 92 @content.comments = nil
74 if request.get? 93
75 # To prevent StaleObjectError exception when reverting to a previous version 94 # To prevent StaleObjectError exception when reverting to a previous version
76 @content.version = @page.content.version 95 @content.version = @page.content.version
77 else
78 if !@page.new_record? && @content.text == params[:content][:text]
79 attachments = Attachment.attach_files(@page, params[:attachments])
80 render_attachment_warning_if_needed(@page)
81 # don't save if text wasn't changed
82 redirect_to :action => 'index', :id => @project, :page => @page.title
83 return
84 end
85 #@content.text = params[:content][:text]
86 #@content.comments = params[:content][:comments]
87 @content.attributes = params[:content]
88 @content.author = User.current
89 # if page is new @page.save will also save content, but not if page isn't a new record
90 if (@page.new_record? ? @page.save : @content.save)
91 attachments = Attachment.attach_files(@page, params[:attachments])
92 render_attachment_warning_if_needed(@page)
93 call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
94 redirect_to :action => 'index', :id => @project, :page => @page.title
95 end
96 end
97 rescue ActiveRecord::StaleObjectError 96 rescue ActiveRecord::StaleObjectError
98 # Optimistic locking exception 97 # Optimistic locking exception
99 flash[:error] = l(:notice_locking_conflict) 98 flash[:error] = l(:notice_locking_conflict)
100 end 99 end
101 100
101 verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
102 # Creates a new page or updates an existing one
103 def update
104 @page = @wiki.find_or_new_page(params[:id])
105 return render_403 unless editable?
106 @page.content = WikiContent.new(:page => @page) if @page.new_record?
107
108 @content = @page.content_for_version(params[:version])
109 @content.text = initial_page_content(@page) if @content.text.blank?
110 # don't keep previous comment
111 @content.comments = nil
112
113 if !@page.new_record? && params[:content].present? && @content.text == params[:content][:text]
114 attachments = Attachment.attach_files(@page, params[:attachments])
115 render_attachment_warning_if_needed(@page)
116 # don't save if text wasn't changed
117 redirect_to :action => 'show', :project_id => @project, :id => @page.title
118 return
119 end
120 @content.attributes = params[:content]
121 @content.author = User.current
122 # if page is new @page.save will also save content, but not if page isn't a new record
123 if (@page.new_record? ? @page.save : @content.save)
124 attachments = Attachment.attach_files(@page, params[:attachments])
125 render_attachment_warning_if_needed(@page)
126 call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
127 redirect_to :action => 'show', :project_id => @project, :id => @page.title
128 end
129
130 rescue ActiveRecord::StaleObjectError
131 # Optimistic locking exception
132 flash[:error] = l(:notice_locking_conflict)
133 end
134
102 # rename a page 135 # rename a page
103 def rename 136 def rename
104 return render_403 unless editable? 137 return render_403 unless editable?
105 @page.redirect_existing_links = true 138 @page.redirect_existing_links = true
106 # used to display the *original* title if some AR validation errors occur 139 # used to display the *original* title if some AR validation errors occur
107 @original_title = @page.pretty_title 140 @original_title = @page.pretty_title
108 if request.post? && @page.update_attributes(params[:wiki_page]) 141 if request.post? && @page.update_attributes(params[:wiki_page])
109 flash[:notice] = l(:notice_successful_update) 142 flash[:notice] = l(:notice_successful_update)
110 redirect_to :action => 'index', :id => @project, :page => @page.title 143 redirect_to :action => 'show', :project_id => @project, :id => @page.title
111 end 144 end
112 end 145 end
113 146
114 def protect 147 def protect
115 @page.update_attribute :protected, params[:protected] 148 @page.update_attribute :protected, params[:protected]
116 redirect_to :action => 'index', :id => @project, :page => @page.title 149 redirect_to :action => 'show', :project_id => @project, :id => @page.title
117 end 150 end
118 151
119 # show page history 152 # show page history
120 def history 153 def history
121 @version_count = @page.content.versions.count 154 @version_count = @page.content.versions.count
137 170
138 def annotate 171 def annotate
139 @annotate = @page.annotate(params[:version]) 172 @annotate = @page.annotate(params[:version])
140 render_404 unless @annotate 173 render_404 unless @annotate
141 end 174 end
142 175
176 verify :method => :delete, :only => [:destroy], :redirect_to => { :action => :show }
143 # Removes a wiki page and its history 177 # Removes a wiki page and its history
144 # Children can be either set as root pages, removed or reassigned to another parent page 178 # Children can be either set as root pages, removed or reassigned to another parent page
145 def destroy 179 def destroy
146 return render_403 unless editable? 180 return render_403 unless editable?
147 181
164 @reassignable_to = @wiki.pages - @page.self_and_descendants 198 @reassignable_to = @wiki.pages - @page.self_and_descendants
165 return 199 return
166 end 200 end
167 end 201 end
168 @page.destroy 202 @page.destroy
169 redirect_to :action => 'special', :id => @project, :page => 'Page_index' 203 redirect_to :action => 'index', :project_id => @project
170 end 204 end
171 205
172 # display special pages 206 # Export wiki to a single html file
173 def special 207 def export
174 page_title = params[:page].downcase 208 if User.current.allowed_to?(:export_wiki_pages, @project)
175 case page_title 209 @pages = @wiki.pages.find :all, :order => 'title'
176 # show pages index, sorted by title 210 export = render_to_string :action => 'export_multiple', :layout => false
177 when 'page_index', 'date_index' 211 send_data(export, :type => 'text/html', :filename => "wiki.html")
178 # eager load information about last updates, without loading text
179 @pages = @wiki.pages.find :all, :select => "#{WikiPage.table_name}.*, #{WikiContent.table_name}.updated_on",
180 :joins => "LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id",
181 :order => 'title'
182 @pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
183 @pages_by_parent_id = @pages.group_by(&:parent_id)
184 # export wiki to a single html file
185 when 'export'
186 if User.current.allowed_to?(:export_wiki_pages, @project)
187 @pages = @wiki.pages.find :all, :order => 'title'
188 export = render_to_string :action => 'export_multiple', :layout => false
189 send_data(export, :type => 'text/html', :filename => "wiki.html")
190 else
191 redirect_to :action => 'index', :id => @project, :page => nil
192 end
193 return
194 else 212 else
195 # requested special page doesn't exist, redirect to default page 213 redirect_to :action => 'show', :project_id => @project, :id => nil
196 redirect_to :action => 'index', :id => @project, :page => nil 214 end
197 return 215 end
198 end 216
199 render :action => "special_#{page_title}" 217 def date_index
218 load_pages_grouped_by_date_without_content
200 end 219 end
201 220
202 def preview 221 def preview
203 page = @wiki.find_page(params[:page]) 222 page = @wiki.find_page(params[:id])
204 # page is nil when previewing a new page 223 # page is nil when previewing a new page
205 return render_403 unless page.nil? || editable?(page) 224 return render_403 unless page.nil? || editable?(page)
206 if page 225 if page
207 @attachements = page.attachments 226 @attachements = page.attachments
208 @previewed = page.content 227 @previewed = page.content
213 232
214 def add_attachment 233 def add_attachment
215 return render_403 unless editable? 234 return render_403 unless editable?
216 attachments = Attachment.attach_files(@page, params[:attachments]) 235 attachments = Attachment.attach_files(@page, params[:attachments])
217 render_attachment_warning_if_needed(@page) 236 render_attachment_warning_if_needed(@page)
218 redirect_to :action => 'index', :page => @page.title 237 redirect_to :action => 'show', :id => @page.title, :project_id => @project
219 end 238 end
220 239
221 private 240 private
222 241
223 def find_wiki 242 def find_wiki
224 @project = Project.find(params[:id]) 243 @project = Project.find(params[:project_id])
225 @wiki = @project.wiki 244 @wiki = @project.wiki
226 render_404 unless @wiki 245 render_404 unless @wiki
227 rescue ActiveRecord::RecordNotFound 246 rescue ActiveRecord::RecordNotFound
228 render_404 247 render_404
229 end 248 end
230 249
231 # Finds the requested page and returns a 404 error if it doesn't exist 250 # Finds the requested page and returns a 404 error if it doesn't exist
232 def find_existing_page 251 def find_existing_page
233 @page = @wiki.find_page(params[:page]) 252 @page = @wiki.find_page(params[:id])
234 render_404 if @page.nil? 253 render_404 if @page.nil?
235 end 254 end
236 255
237 # Returns true if the current user is allowed to edit the page, otherwise false 256 # Returns true if the current user is allowed to edit the page, otherwise false
238 def editable?(page = @page) 257 def editable?(page = @page)
243 def initial_page_content(page) 262 def initial_page_content(page)
244 helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting) 263 helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
245 extend helper unless self.instance_of?(helper) 264 extend helper unless self.instance_of?(helper)
246 helper.instance_method(:initial_page_content).bind(self).call(page) 265 helper.instance_method(:initial_page_content).bind(self).call(page)
247 end 266 end
267
268 # eager load information about last updates, without loading text
269 def load_pages_grouped_by_date_without_content
270 @pages = @wiki.pages.find :all, :select => "#{WikiPage.table_name}.*, #{WikiContent.table_name}.updated_on",
271 :joins => "LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id",
272 :order => 'title'
273 @pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
274 @pages_by_parent_id = @pages.group_by(&:parent_id)
275 end
276
248 end 277 end