blob: be20b76d920a58de006e70d79b97792dfc1e9342 [file] [log] [blame]
class PagesController < ApplicationController
before_filter :authenticate, :except => [:view]
before_filter :authenticate_cadmin, :only => [:destroy]
caches_page :view
#--
# TODO check that we really need this
#++
cache_sweeper :sweeper, :only => [:checkout, :checkin, :undocheckout, :destroy, :discussion]
layout 'wiki'
FLASH_CHECKIN_SUCCESS = "Check-in succesfull, please add or update the version note!"
def view
logger.debug("params[:url]:" + params[:url])
parts = params[:url].sub(ENV['EPFWIKI_BASE_URL'] + '/', '').split('?').first.split('/') # url sometimes contains a parameter!
@wiki = Wiki.find_by_folder(parts.shift(2).second) # first part is folder that contains the Wiki sites, the second part is the Wiki folder
@rel_path = parts.join('/') # rel path is parts that remain
@page = WikiPage.find_by_rel_path_and_site_id(@rel_path, @wiki.id)
if @page
logger.debug("Page found")
@version = @page.current_version
@comments = Comment.find(:all, :conditions => ["page_id=? and site_id=?", @page.id, @wiki.id], :order => 'created_on ASC')
@checkout = @page.checkout
logger.debug("@version: #{@version.inspect}")
@contributor_names = @page.contributors
else
logger.error("Page not found with @rel_path #{@rel_path} and @wiki.id #{@wiki.id}")
end
@checkout_text = "This page is currently being created or modified by #{@checkout.user.name}" if @checkout and @version
respond_to do |format|
format.js
end
end
def discussion
if request.get?
@wiki = Wiki.find_by_folder(params[:site_folder])
@page = Page.find(params[:id])
@comment = Comment.new(:site => @wiki, :page => @page)
else
@comment = Comment.new(params[:comment].merge(:user => session_user))
@page = @comment.page
@wiki = @page.site
@comment.version = @page.current_version
if @comment.save
redirect_to :controller => 'pages', :site_folder => @wiki.folder, :id => @page.id, :action => 'discussion'
users = (User.find(:all, :conditions => ['notify_immediate=?', 1]) + Notification.find_all_users(@page, Page.name)).uniq
users += Notification.find_all_users(@wiki, 'Immediate')
unless users.empty?
subject = "New comment about #{@page.presentation_name}"
introduction = "User #{@comment.user.name} created a comment about <a href=\"#{@comment.page.url}\">#{@comment.page.presentation_name}</a> in site #{@comment.site.title}<br>"
Notifier.notification(users.uniq,subject,introduction, @comment.text).deliver
end
end
end
@comments = Comment.find(:all, :conditions => ["page_id=? and site_id=?", @page.id, @wiki.id], :order => 'created_on ASC')
end
def edit
if params[:checkout_id]
@checkout = Checkout.find(params[:checkout_id])
v0 = @checkout.version.previous_version
if v0 and v0.version == 0 # v0 can be in nil in case of new page
unless File.exists? v0.path(true) # we also want version 0 in TinyMCE format
h = v0.html
h = h.gsub(Page::BODY_TAG_PATTERN, '<body>')
h = h.gsub(Page::TREEBROWSER_PATTERN, Page::TREEBROWSER_PLACEHOLDER)
h = h.gsub(Page::HEAD_PATTERN, '')
@version0_html = h
end
end
@page = @checkout.page
@wiki = @checkout.site
render :layout => false
else
redirect_to :action => 'checkout', :id => params[:id], :site_folder => params[:site_folder]
end
end
# Action #checkout to create a new checkout
def checkout
if request.get?
@version = UserVersion.new
@page = Page.find(params[:id])
@wiki = @page.site
#--
#@wiki = Wiki.find_by_folder(params[:site_folder])
# TODO these kind of statement are no longer necessary,
# do global search and replace
#++
@version.wiki = @wiki
co = @page.checkout
if co
redirect_to :action => 'edit', :checkout_id => co.id
else
@version.source_version = @page.current_version
end
else
logger.info("Creating new checkout using params #{params[:user_version].inspect}")
@version = UserVersion.new(params[:user_version])
@version.source_version = Version.find(@version.version_id) # TODO
@page = @version.source_version.page
@wiki = @page.site
co = Checkout.new(:note => @version.note, :page => @page, :site => @wiki, :source_version => @version.source_version, :user => session_user, :version => @version )
if co.save
redirect_to :action => 'edit', :checkout_id => co.id
else
logger.info("Failed to save checkout #{co.inspect}")
end
end
@versions = @page.versions
end
# #save the HTML after checking that the User is the owner. The Page remains checked-out.
def save
@checkout = Checkout.find(params[:checkout_id])
raise LoginController::FLASH_UNOT_CADMIN if !mine?(@checkout) && !cadmin?
@checkout.version.html = params[:html]
if params[:html_v0] # will only be present when previous version is version 0
@version0 = @checkout.version.previous_version
@version0.save_tinymce_html(params[:html_v0])
end
@checkout.version.save
if params[:action] == 'save'
redirect_to :action => 'edit', :checkout_id => @checkout.id
else
redirect_to(url_for('/' + @checkout.version.rel_path_root))
end
end
def preview
save
end
# Action #checkin to checkin a page that is checked-out
# TODO force post method
def checkin
if params[:checkout_id]
logger.info("Finding checkout with id #{params[:checkout_id]}")
co = Checkout.find(params[:checkout_id])
@version = co.version
@wiki = co.site
@page = co.page
co.checkin(session_user, params[:html]) # will create Notification record
if params[:html_v0] # will only be present when previous version is version 0
@version0 = co.version.previous_version
@version0.save_tinymce_html(params[:html_v0])
end
raise "Failed to checkin #{checkout.id}" if Checkout.exists?(co.id)
flash.now['success'] = FLASH_CHECKIN_SUCCESS
users = (User.find(:all, :conditions => ['notify_immediate=?', 1]) + Notification.find_all_users(@page, Page.name)).uniq
users += Notification.find_all_users(@wiki, 'Immediate')
unless users.empty?
subject = "New version created of #{@version.page.presentation_name}"
introduction = "User #{@version.user.name} created a version of <a href=\"#{@version.page.url}\">#{@version.page.presentation_name}</a> in site #{@version.wiki.title}<br>"
Notifier.notification(users.uniq,subject,introduction, @version.note).deliver
end
#redirect_to :controller => 'versions', :action => 'edit', :id => version.id
if @version.template?
# Because we use note field to cache the brief description of a template
# the field should be empty. # TODO Maybe we should rethink this use of the note field
@version.note = ''
@version.save!
redirect_to @version.page.url
end
else
logger.debug("Updating version note using params #{params.inspect}")
@version = Version.find(params[:version][:id])
@wiki = @version.wiki
@page = @version.page
if mine?(@version) || cadmin?
#@version.note = params[:version][:note]
if @version.update_attributes(params[:version])
flash['notice'] = Utils::FLASH_RECORD_UPDATED # TODO test this
redirect_to @version.page.url
end
else
flash.now['error'] = Utils::FLASH_NOT_OWNER # TODO test this
end
end
end
# Action #new to create a new Page based on a template or based on another page.
def new
@wiki = Wiki.find_by_folder(params[:site_folder])
@page = Page.find(params[:id])
@page_version = @page.current_version
if request.get?
@new_page = Page.new
@new_page.source_version = @page_version.id if @page_version # TODO a better name would be source_version_id?
else
logger.info("Creating new page with #{params.inspect}")
#@templates = []
version = nil
version = Version.find(params[:page][:source_version]) if params[:page][:source_version]
@new_page, @checkout = WikiPage.new_using_template(params[:page].merge(:user=> session_user, :site => @wiki, :source_version => version))
if @new_page.errors.empty?
if @new_page.save
if @checkout
redirect_to :action => 'edit', :checkout_id => @checkout.id
end
end
else
logger.info("New page has errors: #{@new_page.errors.full_messages.join(', ')}")
end
end
@templates = Site.templates
@templates = ([@page_version] + @templates).compact.uniq # compact because @page_version can be nil
end
#--
# TODO improved security - move authorisation check to Checkout.undo?
#++
def undocheckout
co = Checkout.find(params[:checkout_id])
page = co.page
wiki = co.site
if mine?(co) || cadmin?
co.undo
if Checkout.exists?(co.id)
raise "Failed to undo checkout #{co.id} of page #{co.page.presentation_name}"
else
if Page.exists?(page.id)
redirect_to page.url
else
redirect_to wiki.pages[0].url
end
end
else
raise "This checkout is owned by #{co.user.name}. You cannot undo a checkout that belongs to another user"
end
end
# TODO Implement test
def destroy
@page = Page.find(params[:id])
#paths.each {|path| File.delete(path) if File.exists?(path)} # decided not to delete the files
Checkout.destroy_all(['page_id=?', @page.id])
Comment.destroy_all(['page_id=?', @page.id])
Notification.destroy_all(['page_id=?', @page.id])
Version.destroy_all(['page_id=?', @page.id])
@page.destroy
flash['success'] = "Page #{@page.presentation_name}deleted!"
redirect_to request.referer
end
def history # TODO test
@page = Page.find(params[:id])
@wiki = Wiki.find_by_folder(params[:site_folder])
@versions = @page.versions
@versions << @page.checkout.version unless @page.checkout.nil?
@other_versions = Version.find(:all, :conditions => ['wiki_id<>? and page_id=?', @wiki.id, @page.id], :order=> 'wiki_id, version ASC')
end
def rollback
unless params[:version].nil?
to = Version.find(params[:version][:version_id])
if to.page.checkout.nil?
co = Checkout.new(:user => session_user, :page => to.page, :site => to.wiki, :source_version => to, :note => "Rollback to version #{to.version}")
if co.save
co.checkin(session_user)
flash['success'] = 'Rollback complete'
else
flash['error'] = 'Rollback failed'
end
else
flash['error'] = 'Cannot rollback checked out page'
end
redirect_to :action => 'history', :id => to.page.id, :site_folder => to.wiki.folder
end
end
def text
@page = Page.find(params[:id])
render :inline => "<%= (simple_format(strip_tags(@page.html))) %>", :layout => false
end
# TODO be able to quickly retrieve a list of pages based on content type in a site
#def list
# sidebar
# uma_type = params[:type].capitalize.singularize
# logger.info("Selecting pages with uma_type #{uma_type}")
# @pages = Page.find(:all, :order => 'presentation_name ASC', :conditions => ['uma_type=?', uma_type])
# render :layout => 'application'
#end
end