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