blob: a9424545779e19194c27940a8dd881fa111ac5d3 [file] [log] [blame]
#--######################################################################
# Copyright (c) 2006 Logica
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
#
# Onno van der Straaten:: initial implementation
#++######################################################################
# {Copyright (c) 2006 Logica}[link:files/COPYRIGHT.html]
class WikiPage < Page
# When creating a new page, the page will belong to the user creating the page
belongs_to :user
#--
# TODO database change -> rename page_id to wiki_page_id
#++
has_many :notifications#, :dependent => :destroy
#--
# TODO not working, find out why
#has_many :versions, :foreign_key => 'page_id'
#++
has_many :user_versions, :foreign_key => 'page_id', :conditions => ['version is not null']
has_many :baseline_process_versions, :foreign_key => 'page_id'
#--
# TODO (but now now) anomaly works in the console but not in the application or in tests. Then is always returns nil. Replaced with method
# has_one :checkout, :foreign_key => 'page_id'
#++
#--
# has_many :comments, :foreign_key => 'page_id' #, :dependent => :destroy
# TODO anomaly. the above statement does not work. Comments is always nil. When I change the key
# I see the statement, it looks allright.
# ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'da_texts.page_id_2
# ' in 'where clause': SELECT * FROM `da_texts` WHERE (da_texts.page_id_2 = 1431
# ) AND ( (`da_texts`.`type` = 'Comment' ) )
#++
#--
# FIXME Bugzilla 231125
# acts_as_ferret :fields => [:presentation_name, :tool, :status, :uma_name, :uma_type, :text, :contributors]
#++
def versions
(self.user_versions + self.baseline_process_versions).sort_by{|v|v.version}
end
def checkout
Checkout.find(:first, :conditions => ['page_id=?',self.id])
end
def comments
Comment.find(:all, :order => 'created_on ASC', :conditions => ['page_id=?',self.id])
end
# change 68 TODO remove
def unharvested_versions
Version.find(:all, :order => 'created_on DESC', :conditions => ['page_id = ? and done=?',self.id, 'N'])
end
#--
# TODO not sure if this is used
#++
def harvested?
self.unharvested_versions.size == 0
end
# Method #new_using_template requires presentation_name, note, site, user and source_version and returns: page, checkout.
# For an example see PagesController.new
#--
# TODO new_using_template when there is already a checkout causes error without clear message
#++
def self.new_using_template(params)
logger.info("Creating new page using params: #{params.inspect}" )
sv = Version.find(params[:source_version])
p = sv.page.clone
p.site = params[:site]
p.tool = 'Wiki'
p.user = params[:user]
p.presentation_name = params[:presentation_name]
p.filename = p.presentation_name.downcase.delete('&+-.\"/\[]:;=,').tr(' ','_') + '.html' if !p.presentation_name.blank?
old_path = File.expand_path(p.filename, File.dirname(sv.path))
if sv.class.name == UserVersion.name
p.rel_path = old_path.gsub(sv.wiki.path + '/','')
else
p.rel_path = old_path.gsub(sv.baseline_process.path + '/','')
end
# make the rel_path unique, this way we can create multiple pages with the same presentation name
unique = false
while !unique
if Page.exists?(['rel_path = ? and site_id = ?',p.rel_path, p.site.id])
p.make_rel_path_unique
else
unique = true
end
end
logger.debug("New path is #{p.rel_path}, site path is #{sv.wiki.path}, old_path is #{old_path}")
h = sv.html
h = h.gsub(/<meta.*? name="uma\.presentationName".*?>/, '<meta content="' + p.presentation_name + '" name="uma.presentationName">')
h = h.gsub(TITLE_PATTERN, "<title>#{p.presentation_name}</title>")
h = h.gsub(TITLE2_PATTERN, 'class="pageTitle">' + p.presentation_name + '<\/td>') # TODO don't think this is working, but there is a workaround
p.html = h
Page.enhance_file(p.path)
if p.save
logger.info("Page saved, creating co")
co = Checkout.new(:note => p.note, :page => p, :site => p.site, :source_version => sv, :user => params[:user], :html => h)
logger.debug("creating co: #{co.inspect}")
co.save
Notification.find_or_create(p, params[:user], Page.name)
return p, co
else
logger.info("Failed to save page, returned unsaved page")
return p, nil
end
end
def max_version_no
max = Version.maximum('version', :conditions => ['page_id=? and wiki_id = ?',self.id, self.site.id])
max = 0 if max.nil? # max can be zero when creating new pages, there is no BaselineProcessVersion only a UserVersion
return max
end
# Method #current_version=(version) makes the version the current version of the page
#--
# TODO this method should also do the html stuff
#++
def current_version=(v)
v2 = self.current_version
if v2 && v2.current
v2.current = false
v2.save!
end
if v
logger.info("Making version #{v.id} the current version")
v.current = true
v.save!
end
return v
end
# Method #current_version returns the current version of the page
def current_version
logger.debug("Finding current version of page #{self.presentation_name}")
version = Version.find(:first ,:conditions => ["page_id=? and current = ?", self.id, true]) #TODO check that true works instead of 1
version = Version.find(:first ,:order => "version DESC", :conditions => ["page_id=? and version is not null", self.id]) if version.nil?
version = version.previous_version if !version.nil? && version.checkout #NOTE: version can be nil, it will be nil when creating a new page
return version
end
# Method #last_version return the last created version (the version with the highest version number). Versions that are
# part of a checkout are excluded (version is nil for those versions)
def last_version
return Version.find(:first ,:order => 'version DESC', :conditions => ["page_id=? and version is not null", self.id])
end
def contributors
(self.user_versions.collect {|v|v.user.name} + self.comments.collect {|c|c.user.name}).uniq
end
# See also #Page.html
def html=(h)
logger.debug("Writing html to #{self.path}")
d = File.dirname(self.path)
File.makedirs(d) if !File.exists?(d) # In case of a new page being created using a template, the dir possible doesn't exist yet
f = File.new(self.path, "w")
f.puts(h)
f.close
end
# Example wiki.pages.active
def self.active
find(:all, :conditions=>["status = ? or status = ?", 'New','Updated'])
end
# TODO Bugzilla 231125
# A method like below could be used to create a good index for finding pages
#def text
# t = read_attribute('text')
# if t.blank?
# t = self.html.gsub(/<\/?[^>]*>/, '')
# t += self.comments.collect {|c|c.text}
# t += self.versions.collect {|v|v.note}
# write_attribute('text', t)
# end
# t
#end
def other_pages_with_comments
returning pages = [] do
WikiPage.find(:all, :conditions => ['rel_path = ? and id <> ?', self.rel_path, self.id]).each do |p|
pages << p if Comment.count(:conditions => ['page_id =?', self.id]) > 0
end
end
end
def other_pages_with_versions
returning pages = [] do
WikiPage.find(:all, :conditions => ['rel_path = ? and id <> ?', self.rel_path, self.id]).each do |p|
pages << p if Version.count(:conditions => ['page_id =? and baseline_process_id is null', self.id]) > 0
end
end
end
def wikis
return WikiPage.find(:all, :conditions => ['rel_path=?', self.rel_path]).collect {|p|p.site}
end
def comments_in_other_wikis_count
Comment.count(:conditions => ['site_id in (?) and page_id <> ?', WikiPage.find(:all, :conditions => ['rel_path=?', self.rel_path]).collect{|p|p.id}, self.id])
end
def versions_in_other_wikis
Version.find(:all, :conditions => ['wiki_id in ? and baseline_process_id is null and page_id <> ?', WikiPage.find(:all, :rel_path => self.rel_path).collect{|p|p.id}, self.id])
end
def versions_in_other_wikis_count
ids = WikiPage.find(:all, :conditions => ['rel_path=?', self.rel_path]).collect{|p|p.id}
Version.count(:conditions => ['wiki_id in (?) and baseline_process_id is null and page_id <> ?', ids , self.id])
end
def checkedout?
!self.checkout.nil?
end
# TODO add check that if the page is a new page (tool = 'Wiki'), the user needs to be set
# Make rel_path unique if it isn't unique. Used for creating new pages with the same presentation name.
# Only used by WikiPage.new_using_template
def make_rel_path_unique
match = /_([\d]+)\.html/.match(self.rel_path)
if match
nr = (match[1].to_i + 1)
self.rel_path = self.rel_path.gsub(match[0], "_#{nr}.html")
else
self.rel_path = self.rel_path.gsub('.html', '_1.html')
end
end
end