| #--###################################################################### |
| # 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 |