mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
BUGFIX/FEATURE: store topic changes in post revisions
History + edit notifications for title and category changes
This commit is contained in:
@@ -1,8 +1,96 @@
|
||||
require_dependency "discourse_diff"
|
||||
|
||||
class PostRevision < ActiveRecord::Base
|
||||
belongs_to :post
|
||||
belongs_to :user
|
||||
|
||||
serialize :modifications, Hash
|
||||
|
||||
def body_changes
|
||||
changes_for("cooked", "raw")
|
||||
end
|
||||
|
||||
def category_changes
|
||||
{
|
||||
previous_category_id: previous("category_id"),
|
||||
current_category_id: current("category_id"),
|
||||
}
|
||||
end
|
||||
|
||||
def title_changes
|
||||
changes_for("title", nil, true)
|
||||
end
|
||||
|
||||
def changes_for(name, markdown=nil, wrap=false)
|
||||
prev = previous(name)
|
||||
cur = current(name)
|
||||
|
||||
if wrap
|
||||
prev = "<div>#{CGI::escapeHTML(prev)}</div>"
|
||||
cur = "<div>#{CGI::escapeHTML(cur)}</div>"
|
||||
end
|
||||
|
||||
diff = DiscourseDiff.new(prev, cur)
|
||||
|
||||
result = {
|
||||
inline: diff.inline_html,
|
||||
side_by_side: diff.side_by_side_html
|
||||
}
|
||||
|
||||
if markdown
|
||||
diff = DiscourseDiff.new(previous(markdown), current(markdown))
|
||||
result[:side_by_side_markdown] = diff.side_by_side_markdown
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def previous(field)
|
||||
lookup_with_fallback(field, 0)
|
||||
end
|
||||
|
||||
def current(field)
|
||||
lookup_with_fallback(field, 1)
|
||||
end
|
||||
|
||||
def previous_revisions
|
||||
@previous_revs ||=
|
||||
PostRevision.where("post_id = ? AND number < ?",
|
||||
post_id, number
|
||||
)
|
||||
.order("number desc")
|
||||
.to_a
|
||||
end
|
||||
|
||||
def has_topic_data?
|
||||
post && post.post_number == 1
|
||||
end
|
||||
|
||||
def lookup_with_fallback(field, index)
|
||||
|
||||
unless val = lookup(field, index)
|
||||
previous_revisions.each do |v|
|
||||
break if val = v.lookup(field, 1)
|
||||
end
|
||||
end
|
||||
|
||||
unless val
|
||||
if ["cooked","raw"].include?(field)
|
||||
val = post.send(field)
|
||||
else
|
||||
val = post.topic.send(field)
|
||||
end
|
||||
end
|
||||
|
||||
val
|
||||
end
|
||||
|
||||
def lookup(field, index)
|
||||
if mod = modifications[field]
|
||||
mod[index]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# == Schema Information
|
||||
|
||||
@@ -92,7 +92,6 @@ class Topic < ActiveRecord::Base
|
||||
has_many :topic_invites
|
||||
has_many :invites, through: :topic_invites, source: :invite
|
||||
|
||||
has_many :topic_revisions
|
||||
has_many :revisions, foreign_key: :topic_id, class_name: 'TopicRevision'
|
||||
|
||||
# When we want to temporarily attach some data to a forum topic (usually before serialization)
|
||||
@@ -189,13 +188,20 @@ class Topic < ActiveRecord::Base
|
||||
|
||||
end
|
||||
|
||||
# TODO move into PostRevisor or TopicRevisor
|
||||
def save_revision
|
||||
TopicRevision.create!(
|
||||
user_id: acting_user.id,
|
||||
topic_id: id,
|
||||
number: TopicRevision.where(topic_id: id).count + 2,
|
||||
modifications: changes.extract!(:category, :title)
|
||||
)
|
||||
if first_post_id = posts.where(post_number: 1).pluck(:id).first
|
||||
|
||||
number = PostRevision.where(post_id: first_post_id).count + 2
|
||||
PostRevision.create!(
|
||||
user_id: acting_user.id,
|
||||
post_id: first_post_id,
|
||||
number: number,
|
||||
modifications: changes.extract!(:category_id, :title)
|
||||
)
|
||||
|
||||
Post.update_all({version: number}, id: first_post_id)
|
||||
end
|
||||
end
|
||||
|
||||
def should_create_new_version?
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
class TopicRevision < ActiveRecord::Base
|
||||
belongs_to :topic
|
||||
belongs_to :user
|
||||
|
||||
serialize :modifications, Hash
|
||||
end
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: topic_revisions
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer
|
||||
# topic_id :integer
|
||||
# modifications :text
|
||||
# number :integer
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_topic_revisions_on_topic_id (topic_id)
|
||||
# index_topic_revisions_on_topic_id_and_number (topic_id,number)
|
||||
#
|
||||
Reference in New Issue
Block a user