annotate app/controllers/.svn/text-base/wiki_controller.rb.svn-base @ 45:65d9e2cabaa3 luisf

Added tipoftheday to the config/settings in order to correct previous issues. Tip of the day is now working correctly. Added the heading strings to the locales files.
author luisf
date Tue, 23 Nov 2010 11:50:01 +0000
parents 94944d00e43c
children af80e5618e9b
rev   line source
Chris@0 1 # redMine - project management software
Chris@0 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
Chris@0 3 #
Chris@0 4 # This program is free software; you can redistribute it and/or
Chris@0 5 # modify it under the terms of the GNU General Public License
Chris@0 6 # as published by the Free Software Foundation; either version 2
Chris@0 7 # of the License, or (at your option) any later version.
Chris@0 8 #
Chris@0 9 # This program is distributed in the hope that it will be useful,
Chris@0 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@0 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 12 # GNU General Public License for more details.
Chris@0 13 #
Chris@0 14 # You should have received a copy of the GNU General Public License
Chris@0 15 # along with this program; if not, write to the Free Software
Chris@0 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Chris@0 17
Chris@0 18 require 'diff'
Chris@0 19
chris@37 20 # The WikiController follows the Rails REST controller pattern but with
chris@37 21 # a few differences
chris@37 22 #
chris@37 23 # * index - shows a list of WikiPages grouped by page or date
chris@37 24 # * new - not used
chris@37 25 # * create - not used
chris@37 26 # * show - will also show the form for creating a new wiki page
chris@37 27 # * edit - used to edit an existing or new page
chris@37 28 # * update - used to save a wiki page update to the database, including new pages
chris@37 29 # * destroy - normal
chris@37 30 #
chris@37 31 # Other member and collection methods are also used
chris@37 32 #
chris@37 33 # TODO: still being worked on
Chris@0 34 class WikiController < ApplicationController
Chris@0 35 default_search_scope :wiki_pages
Chris@0 36 before_filter :find_wiki, :authorize
Chris@0 37 before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy]
Chris@0 38
chris@37 39 verify :method => :post, :only => [:protect], :redirect_to => { :action => :show }
Chris@0 40
Chris@0 41 helper :attachments
Chris@0 42 include AttachmentsHelper
Chris@0 43 helper :watchers
chris@37 44
chris@37 45 # List of pages, sorted alphabetically and by parent (hierarchy)
chris@37 46 def index
chris@37 47 load_pages_grouped_by_date_without_content
chris@37 48 end
chris@37 49
Chris@0 50 # display a page (in editing mode if it doesn't exist)
chris@37 51 def show
chris@37 52 page_title = params[:id]
Chris@0 53 @page = @wiki.find_or_new_page(page_title)
Chris@0 54 if @page.new_record?
Chris@0 55 if User.current.allowed_to?(:edit_wiki_pages, @project) && editable?
Chris@0 56 edit
Chris@0 57 render :action => 'edit'
Chris@0 58 else
Chris@0 59 render_404
Chris@0 60 end
Chris@0 61 return
Chris@0 62 end
Chris@0 63 if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
Chris@0 64 # Redirects user to the current version if he's not allowed to view previous versions
Chris@0 65 redirect_to :version => nil
Chris@0 66 return
Chris@0 67 end
Chris@0 68 @content = @page.content_for_version(params[:version])
Chris@0 69 if User.current.allowed_to?(:export_wiki_pages, @project)
Chris@0 70 if params[:format] == 'html'
Chris@0 71 export = render_to_string :action => 'export', :layout => false
Chris@0 72 send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
Chris@0 73 return
Chris@0 74 elsif params[:format] == 'txt'
Chris@0 75 send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
Chris@0 76 return
Chris@0 77 end
Chris@0 78 end
Chris@0 79 @editable = editable?
Chris@0 80 render :action => 'show'
Chris@0 81 end
Chris@0 82
Chris@0 83 # edit an existing page or a new one
Chris@0 84 def edit
chris@37 85 @page = @wiki.find_or_new_page(params[:id])
Chris@0 86 return render_403 unless editable?
Chris@0 87 @page.content = WikiContent.new(:page => @page) if @page.new_record?
Chris@0 88
Chris@0 89 @content = @page.content_for_version(params[:version])
Chris@0 90 @content.text = initial_page_content(@page) if @content.text.blank?
Chris@0 91 # don't keep previous comment
Chris@0 92 @content.comments = nil
chris@37 93
chris@37 94 # To prevent StaleObjectError exception when reverting to a previous version
chris@37 95 @content.version = @page.content.version
Chris@0 96 rescue ActiveRecord::StaleObjectError
Chris@0 97 # Optimistic locking exception
Chris@0 98 flash[:error] = l(:notice_locking_conflict)
Chris@0 99 end
chris@37 100
chris@37 101 verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
chris@37 102 # Creates a new page or updates an existing one
chris@37 103 def update
chris@37 104 @page = @wiki.find_or_new_page(params[:id])
chris@37 105 return render_403 unless editable?
chris@37 106 @page.content = WikiContent.new(:page => @page) if @page.new_record?
chris@37 107
chris@37 108 @content = @page.content_for_version(params[:version])
chris@37 109 @content.text = initial_page_content(@page) if @content.text.blank?
chris@37 110 # don't keep previous comment
chris@37 111 @content.comments = nil
chris@37 112
chris@37 113 if !@page.new_record? && params[:content].present? && @content.text == params[:content][:text]
chris@37 114 attachments = Attachment.attach_files(@page, params[:attachments])
chris@37 115 render_attachment_warning_if_needed(@page)
chris@37 116 # don't save if text wasn't changed
chris@37 117 redirect_to :action => 'show', :project_id => @project, :id => @page.title
chris@37 118 return
chris@37 119 end
chris@37 120 @content.attributes = params[:content]
chris@37 121 @content.author = User.current
chris@37 122 # if page is new @page.save will also save content, but not if page isn't a new record
chris@37 123 if (@page.new_record? ? @page.save : @content.save)
chris@37 124 attachments = Attachment.attach_files(@page, params[:attachments])
chris@37 125 render_attachment_warning_if_needed(@page)
chris@37 126 call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
chris@37 127 redirect_to :action => 'show', :project_id => @project, :id => @page.title
chris@37 128 end
chris@37 129
chris@37 130 rescue ActiveRecord::StaleObjectError
chris@37 131 # Optimistic locking exception
chris@37 132 flash[:error] = l(:notice_locking_conflict)
chris@37 133 end
chris@37 134
Chris@0 135 # rename a page
Chris@0 136 def rename
Chris@0 137 return render_403 unless editable?
Chris@0 138 @page.redirect_existing_links = true
Chris@0 139 # used to display the *original* title if some AR validation errors occur
Chris@0 140 @original_title = @page.pretty_title
Chris@0 141 if request.post? && @page.update_attributes(params[:wiki_page])
Chris@0 142 flash[:notice] = l(:notice_successful_update)
chris@37 143 redirect_to :action => 'show', :project_id => @project, :id => @page.title
Chris@0 144 end
Chris@0 145 end
Chris@0 146
Chris@0 147 def protect
Chris@0 148 @page.update_attribute :protected, params[:protected]
chris@37 149 redirect_to :action => 'show', :project_id => @project, :id => @page.title
Chris@0 150 end
Chris@0 151
Chris@0 152 # show page history
Chris@0 153 def history
Chris@0 154 @version_count = @page.content.versions.count
Chris@0 155 @version_pages = Paginator.new self, @version_count, per_page_option, params['p']
Chris@0 156 # don't load text
Chris@0 157 @versions = @page.content.versions.find :all,
Chris@0 158 :select => "id, author_id, comments, updated_on, version",
Chris@0 159 :order => 'version DESC',
Chris@0 160 :limit => @version_pages.items_per_page + 1,
Chris@0 161 :offset => @version_pages.current.offset
Chris@0 162
Chris@0 163 render :layout => false if request.xhr?
Chris@0 164 end
Chris@0 165
Chris@0 166 def diff
Chris@0 167 @diff = @page.diff(params[:version], params[:version_from])
Chris@0 168 render_404 unless @diff
Chris@0 169 end
Chris@0 170
Chris@0 171 def annotate
Chris@0 172 @annotate = @page.annotate(params[:version])
Chris@0 173 render_404 unless @annotate
Chris@0 174 end
chris@37 175
chris@37 176 verify :method => :delete, :only => [:destroy], :redirect_to => { :action => :show }
Chris@0 177 # Removes a wiki page and its history
Chris@0 178 # Children can be either set as root pages, removed or reassigned to another parent page
Chris@0 179 def destroy
Chris@0 180 return render_403 unless editable?
Chris@0 181
Chris@0 182 @descendants_count = @page.descendants.size
Chris@0 183 if @descendants_count > 0
Chris@0 184 case params[:todo]
Chris@0 185 when 'nullify'
Chris@0 186 # Nothing to do
Chris@0 187 when 'destroy'
Chris@0 188 # Removes all its descendants
Chris@0 189 @page.descendants.each(&:destroy)
Chris@0 190 when 'reassign'
Chris@0 191 # Reassign children to another parent page
Chris@0 192 reassign_to = @wiki.pages.find_by_id(params[:reassign_to_id].to_i)
Chris@0 193 return unless reassign_to
Chris@0 194 @page.children.each do |child|
Chris@0 195 child.update_attribute(:parent, reassign_to)
Chris@0 196 end
Chris@0 197 else
Chris@0 198 @reassignable_to = @wiki.pages - @page.self_and_descendants
Chris@0 199 return
Chris@0 200 end
Chris@0 201 end
Chris@0 202 @page.destroy
chris@37 203 redirect_to :action => 'index', :project_id => @project
Chris@0 204 end
Chris@0 205
chris@37 206 # Export wiki to a single html file
chris@37 207 def export
chris@37 208 if User.current.allowed_to?(:export_wiki_pages, @project)
chris@37 209 @pages = @wiki.pages.find :all, :order => 'title'
chris@37 210 export = render_to_string :action => 'export_multiple', :layout => false
chris@37 211 send_data(export, :type => 'text/html', :filename => "wiki.html")
Chris@0 212 else
chris@37 213 redirect_to :action => 'show', :project_id => @project, :id => nil
Chris@0 214 end
chris@37 215 end
chris@37 216
chris@37 217 def date_index
chris@37 218 load_pages_grouped_by_date_without_content
Chris@0 219 end
Chris@0 220
Chris@0 221 def preview
chris@37 222 page = @wiki.find_page(params[:id])
Chris@0 223 # page is nil when previewing a new page
Chris@0 224 return render_403 unless page.nil? || editable?(page)
Chris@0 225 if page
Chris@0 226 @attachements = page.attachments
Chris@0 227 @previewed = page.content
Chris@0 228 end
Chris@0 229 @text = params[:content][:text]
Chris@0 230 render :partial => 'common/preview'
Chris@0 231 end
Chris@0 232
Chris@0 233 def add_attachment
Chris@0 234 return render_403 unless editable?
Chris@0 235 attachments = Attachment.attach_files(@page, params[:attachments])
Chris@0 236 render_attachment_warning_if_needed(@page)
chris@37 237 redirect_to :action => 'show', :id => @page.title, :project_id => @project
Chris@0 238 end
Chris@0 239
Chris@0 240 private
Chris@0 241
Chris@0 242 def find_wiki
chris@37 243 @project = Project.find(params[:project_id])
Chris@0 244 @wiki = @project.wiki
Chris@0 245 render_404 unless @wiki
Chris@0 246 rescue ActiveRecord::RecordNotFound
Chris@0 247 render_404
Chris@0 248 end
Chris@0 249
Chris@0 250 # Finds the requested page and returns a 404 error if it doesn't exist
Chris@0 251 def find_existing_page
chris@37 252 @page = @wiki.find_page(params[:id])
Chris@0 253 render_404 if @page.nil?
Chris@0 254 end
Chris@0 255
Chris@0 256 # Returns true if the current user is allowed to edit the page, otherwise false
Chris@0 257 def editable?(page = @page)
Chris@0 258 page.editable_by?(User.current)
Chris@0 259 end
Chris@0 260
Chris@0 261 # Returns the default content of a new wiki page
Chris@0 262 def initial_page_content(page)
Chris@0 263 helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
Chris@0 264 extend helper unless self.instance_of?(helper)
Chris@0 265 helper.instance_method(:initial_page_content).bind(self).call(page)
Chris@0 266 end
chris@37 267
chris@37 268 # eager load information about last updates, without loading text
chris@37 269 def load_pages_grouped_by_date_without_content
chris@37 270 @pages = @wiki.pages.find :all, :select => "#{WikiPage.table_name}.*, #{WikiContent.table_name}.updated_on",
chris@37 271 :joins => "LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id",
chris@37 272 :order => 'title'
chris@37 273 @pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
chris@37 274 @pages_by_parent_id = @pages.group_by(&:parent_id)
chris@37 275 end
chris@37 276
Chris@0 277 end