You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wiki_content.rb 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. # Redmine - project management software
  2. # Copyright (C) 2006-2013 Jean-Philippe Lang
  3. #
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU General Public License
  6. # as published by the Free Software Foundation; either version 2
  7. # of the License, or (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  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.
  17. require 'zlib'
  18. class WikiContent < ActiveRecord::Base
  19. self.locking_column = 'version'
  20. belongs_to :page, :class_name => 'WikiPage', :foreign_key => 'page_id'
  21. belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
  22. validates_presence_of :text
  23. validates_length_of :comments, :maximum => 255, :allow_nil => true
  24. acts_as_versioned
  25. def visible?(user=User.current)
  26. page.visible?(user)
  27. end
  28. def project
  29. page.project
  30. end
  31. def attachments
  32. page.nil? ? [] : page.attachments
  33. end
  34. # Returns the mail adresses of users that should be notified
  35. def recipients
  36. notified = project.notified_users
  37. notified.reject! {|user| !visible?(user)}
  38. notified.collect(&:mail)
  39. end
  40. # Return true if the content is the current page content
  41. def current_version?
  42. true
  43. end
  44. class Version
  45. belongs_to :page, :class_name => '::WikiPage', :foreign_key => 'page_id'
  46. belongs_to :author, :class_name => '::User', :foreign_key => 'author_id'
  47. attr_protected :data
  48. acts_as_event :title => Proc.new {|o| "#{l(:label_wiki_edit)}: #{o.page.title} (##{o.version})"},
  49. :description => :comments,
  50. :datetime => :updated_on,
  51. :type => 'wiki-page',
  52. :group => :page,
  53. :url => Proc.new {|o| {:controller => 'wiki', :action => 'show', :project_id => o.page.wiki.project, :id => o.page.title, :version => o.version}}
  54. acts_as_activity_provider :type => 'wiki_edits',
  55. :timestamp => "#{WikiContent.versioned_table_name}.updated_on",
  56. :author_key => "#{WikiContent.versioned_table_name}.author_id",
  57. :permission => :view_wiki_edits,
  58. :find_options => {:select => "#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " +
  59. "#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title, " +
  60. "#{WikiContent.versioned_table_name}.page_id, #{WikiContent.versioned_table_name}.author_id, " +
  61. "#{WikiContent.versioned_table_name}.id",
  62. :joins => "LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " +
  63. "LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " +
  64. "LEFT JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Wiki.table_name}.project_id"}
  65. after_destroy :page_update_after_destroy
  66. def text=(plain)
  67. case Setting.wiki_compression
  68. when 'gzip'
  69. begin
  70. self.data = Zlib::Deflate.deflate(plain, Zlib::BEST_COMPRESSION)
  71. self.compression = 'gzip'
  72. rescue
  73. self.data = plain
  74. self.compression = ''
  75. end
  76. else
  77. self.data = plain
  78. self.compression = ''
  79. end
  80. plain
  81. end
  82. def text
  83. @text ||= begin
  84. str = case compression
  85. when 'gzip'
  86. Zlib::Inflate.inflate(data)
  87. else
  88. # uncompressed data
  89. data
  90. end
  91. str.force_encoding("UTF-8") if str.respond_to?(:force_encoding)
  92. str
  93. end
  94. end
  95. def project
  96. page.project
  97. end
  98. # Return true if the content is the current page content
  99. def current_version?
  100. page.content.version == self.version
  101. end
  102. # Returns the previous version or nil
  103. def previous
  104. @previous ||= WikiContent::Version.
  105. reorder('version DESC').
  106. includes(:author).
  107. where("wiki_content_id = ? AND version < ?", wiki_content_id, version).first
  108. end
  109. # Returns the next version or nil
  110. def next
  111. @next ||= WikiContent::Version.
  112. reorder('version ASC').
  113. includes(:author).
  114. where("wiki_content_id = ? AND version > ?", wiki_content_id, version).first
  115. end
  116. private
  117. # Updates page's content if the latest version is removed
  118. # or destroys the page if it was the only version
  119. def page_update_after_destroy
  120. latest = page.content.versions.reorder("#{self.class.table_name}.version DESC").first
  121. if latest && page.content.version != latest.version
  122. raise ActiveRecord::Rollback unless page.content.revert_to!(latest)
  123. elsif latest.nil?
  124. raise ActiveRecord::Rollback unless page.destroy
  125. end
  126. end
  127. end
  128. end