-
Notifications
You must be signed in to change notification settings - Fork 199
/
kb_article.rb
164 lines (131 loc) · 5.53 KB
/
kb_article.rb
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
require 'acts_as_viewed'
require 'acts_as_rated'
require 'acts_as_versioned'
require 'diff'
class KbArticle < ActiveRecord::Base
unloadable
include Redmine::SafeAttributes
self.locking_column = 'version'
self.table_name = "kb_articles"
validates_presence_of :title
validates_presence_of :category_id
belongs_to :project
belongs_to :category, :class_name => "KbCategory"
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
belongs_to :updater, :class_name => 'User', :foreign_key => 'updater_id'
rcrm_acts_as_viewed
acts_as_rated :no_rater => true
rcrm_acts_as_taggable
acts_as_attachable
acts_as_watchable
acts_as_versioned :table_name => :kb_article_versions, :if_changed => [:title, :content, :summary]
self.non_versioned_columns << 'comments_count'
acts_as_event :title => Proc.new {|o| status = (o.new_status ? "(#{l(:label_new_article)})" : nil ); "#{status} #{l(:label_title_articles)} ##{o.id} - #{o.title}" },
:description => :content,
:datetime => :updated_at,
:type => Proc.new { |o| 'article-' + (o.new_status ? 'add' : 'edit') },
:url => Proc.new { |o| {:controller => 'articles', :action => 'show', :id => o.id, :project_id => o.project} }
safe_attributes 'category_id',
'title',
'summary',
'content',
'author_id',
'comments_count',
'project_id',
'updater_id',
'version_comments',
'version',
'tag_list'
# Redmine 3.1.X
if ActiveRecord::VERSION::MAJOR >= 4
acts_as_activity_provider :scope => joins(:project),
:permission => :view_kb_articles,
:author_key => :author_id,
:type => 'kb_articles',
:timestamp => :updated_at
acts_as_searchable :columns => [ "#{table_name}.title", "#{table_name}.summary", "#{table_name}.content"],
:preload => [ :project ],
:date_column => :created_at
scope :visible, lambda {|*args|
joins(:project).
where(Project.allowed_to_condition(args.shift || User.current, :view_kb_articles, *args))}
else
acts_as_activity_provider :find_options => {:include => :project},
:author_key => :author_id,
:type => 'kb_articles',
:timestamp => :updated_at
acts_as_searchable :columns => [ "#{table_name}.title", "#{table_name}.summary", "#{table_name}.content"],
:include => [ :project ],
:order_column => "#{table_name}.id",
:date_column => "#{table_name}.created_at"
scope :visible, lambda {|*args| { :include => :project,
:conditions => Project.allowed_to_condition(args.shift || User.current, :view_kb_articles, *args) } }
end
has_many :comments, -> { order 'created_on DESC' }, :as => :commented, :dependent => :destroy
def recipients
notified = []
# Author and assignee are always notified unless they have been
# locked or don't want to be notified
notified << author if author
notified = notified.select {|u| u.active? && u.notify_about?(self)}
notified.uniq!
notified.collect(&:mail)
end
def editable_by?(user = User.current)
return user.allowed_to?(:edit_articles, self.project) ||
user.allowed_to?(:manage_articles, self.project) ||
(user.allowed_to?(:manage_own_articles, self.project) && self.author_id == user.id)
end
def attachments_deletable?(user = User.current)
editable_by?(user) || super(user)
end
def new_status
if self.updater_id == 0
true
end
end
def content_for_version(version=nil)
result = self.versions.find_by_version(version.to_i) if version
result ||= self
result
end
def diff(version_to=nil, version_from=nil)
version_to = version_to ? version_to.to_i : self.version
version_from = version_from ? version_from.to_i : version_to - 1
version_to, version_from = version_from, version_to unless version_from < version_to
content_to = self.versions.find_by_version(version_to)
content_from = self.versions.find_by_version(version_from)
(content_to && content_from) ? KbDiff.new(content_to, content_from) : nil
end
# Return true if the content is the current page content
def current_version?
true
end
#define the method to auto-remove new versions when reverting
def clear_newer_versions
excess_baggage = send(self.class.version_column).to_i
if excess_baggage > 0
sql = "DELETE FROM #{self.class.versioned_table_name} WHERE version > #{excess_baggage} AND #{self.class.versioned_foreign_key} = #{self.id}"
self.class.versioned_class.connection.execute sql
end
end
def self.count_article_summaries
KbArticle.where("summary is not null and summary <> ''").count
end
class Version
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
belongs_to :updater, :class_name => 'User', :foreign_key => 'updater_id'
# Return true if the content is the current page content
def current_version?
KbArticle.version == self.version
end
end
end
class KbDiff < Redmine::Helpers::Diff
attr_reader :content_to, :content_from
def initialize(content_to, content_from)
@content_to = content_to
@content_from = content_from
super(content_to.content, content_from.content)
end
end