discourse/app/services/topic_timestamp_changer.rb
Andrei Prigorshnev c4d7545f35
FIX: when updating timestamps on topic set a correct bump date (#13746)
There was a bug with changing timestamps using the topic wrench button. Under some circumstances, a topic was disappearing from the top of the latest tab after changing timestamps. Steps to reproduce:
- Choose a topic on the latest tab (the topic should be created some time ago, but has recent posts)
- Change topic timestamps (for example, move them one day forward):
- Go back to the latest tab and see that topic has disappeared.

This PR fixes this. We were setting topic.bumped_at to the timestamp user specified on the modal. This is incorrect. Instead, we should be setting topic.bumped_at to the created_at timestamp of the last regular (not a whisper and so on) post on the topic.
2021-07-16 11:56:51 +04:00

60 lines
1.5 KiB
Ruby

# frozen_string_literal: true
class TopicTimestampChanger
class InvalidTimestampError < StandardError; end
def initialize(timestamp:, topic: nil, topic_id: nil)
@topic = topic || Topic.with_deleted.find(topic_id)
@posts = @topic.posts
@current_timestamp = Time.zone.now
@timestamp = Time.zone.at(timestamp)
raise InvalidTimestampError if @timestamp.to_f > @current_timestamp.to_f
@time_difference = calculate_time_difference
end
def change!
ActiveRecord::Base.transaction do
last_posted_at = @timestamp
@posts.each do |post|
if post.is_first_post?
update_post(post, @timestamp)
else
new_created_at = Time.at(post.created_at.to_f + @time_difference)
new_created_at = @current_timestamp if new_created_at > @current_timestamp
last_posted_at = new_created_at if new_created_at > last_posted_at
update_post(post, new_created_at)
end
end
@topic.reset_bumped_at
update_topic(last_posted_at)
yield(@topic) if block_given?
end
# Burst the cache for stats
[AdminDashboardData, About].each { |klass| Discourse.redis.del klass.stats_cache_key }
end
private
def calculate_time_difference
@timestamp - @topic.created_at
end
def update_topic(last_posted_at)
@topic.update(
created_at: @timestamp,
updated_at: @timestamp,
last_posted_at: last_posted_at
)
end
def update_post(post, timestamp)
post.update(created_at: timestamp, updated_at: timestamp)
end
end