mirror of
https://github.com/discourse/discourse.git
synced 2026-03-04 01:15:08 +08:00
To prepare for the introduction of `CategoryDefaultTimer`, which allows posts created in certain categories to have a default TopicTimer, we need to rename the `topic_id` column to `timerable_id`. --------- Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
127 lines
4.3 KiB
Ruby
127 lines
4.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class TopicTimer < BaseTimer
|
|
belongs_to :user
|
|
belongs_to :topic, foreign_key: :timerable_id
|
|
belongs_to :category
|
|
|
|
validates :user_id, presence: true
|
|
validates :timerable_id, presence: true
|
|
validates :execute_at, presence: true
|
|
validates :status_type, uniqueness: { scope: %i[timerable_id deleted_at] }, if: :public_type?
|
|
validates :status_type,
|
|
uniqueness: {
|
|
scope: %i[timerable_id deleted_at user_id],
|
|
},
|
|
if: :private_type?
|
|
|
|
validate :executed_at_in_future?
|
|
|
|
scope :scheduled_bump_topics,
|
|
-> { where(status_type: TopicTimer.types[:bump], deleted_at: nil).pluck(:timerable_id) }
|
|
scope :pending_timers,
|
|
->(before_time = Time.now.utc) do
|
|
where("execute_at <= :before_time AND deleted_at IS NULL", before_time: before_time)
|
|
end
|
|
|
|
before_save do
|
|
self.created_at ||= Time.zone.now if execute_at
|
|
self.public_type = self.public_type?
|
|
end
|
|
|
|
# These actions are in place to make sure the topic is in the correct
|
|
# state at the point in time where the timer is saved. It does not
|
|
# guarantee that the topic will be in the correct state when the timer
|
|
# job is executed, but each timer job handles deleted topics etc. gracefully.
|
|
#
|
|
# This is also important for the Open Temporarily and Close Temporarily timers,
|
|
# which change the topic's status straight away and set a timer to do the
|
|
# opposite action in the future.
|
|
after_save do
|
|
if (saved_change_to_execute_at? || saved_change_to_user_id?)
|
|
if status_type == TopicTimer.types[:silent_close] || status_type == TopicTimer.types[:close]
|
|
topic.update_status("closed", false, user) if topic.closed?
|
|
end
|
|
if status_type == TopicTimer.types[:open]
|
|
topic.update_status("closed", true, user) if topic.open?
|
|
end
|
|
end
|
|
end
|
|
|
|
def runnable?
|
|
return false if deleted_at.present?
|
|
return false if execute_at > Time.zone.now
|
|
true
|
|
end
|
|
|
|
private
|
|
|
|
def executed_at_in_future?
|
|
return if created_at.blank? || (execute_at > created_at)
|
|
|
|
errors.add(
|
|
:execute_at,
|
|
I18n.t("activerecord.errors.models.topic_timer.attributes.execute_at.in_the_past"),
|
|
)
|
|
end
|
|
|
|
def schedule_auto_delete_replies_job
|
|
Jobs.enqueue(TopicTimer.type_job_map[:delete_replies], topic_timer_id: id)
|
|
end
|
|
|
|
def schedule_auto_bump_job
|
|
Jobs.enqueue(TopicTimer.type_job_map[:bump], topic_timer_id: id)
|
|
end
|
|
|
|
def schedule_auto_open_job
|
|
Jobs.enqueue(TopicTimer.type_job_map[:open], topic_timer_id: id)
|
|
end
|
|
|
|
def schedule_auto_close_job
|
|
Jobs.enqueue(TopicTimer.type_job_map[:close], topic_timer_id: id)
|
|
end
|
|
|
|
def schedule_auto_silent_close_job
|
|
Jobs.enqueue(TopicTimer.type_job_map[:close], topic_timer_id: id, silent: true)
|
|
end
|
|
|
|
def schedule_auto_publish_to_category_job
|
|
Jobs.enqueue(TopicTimer.type_job_map[:publish_to_category], topic_timer_id: id)
|
|
end
|
|
|
|
def schedule_auto_delete_job
|
|
Jobs.enqueue(TopicTimer.type_job_map[:delete], topic_timer_id: id)
|
|
end
|
|
|
|
def schedule_auto_clear_slow_mode_job
|
|
Jobs.enqueue(TopicTimer.type_job_map[:clear_slow_mode], topic_timer_id: id)
|
|
end
|
|
end
|
|
|
|
# == Schema Information
|
|
#
|
|
# Table name: topic_timers
|
|
#
|
|
# id :integer not null, primary key
|
|
# based_on_last_post :boolean default(FALSE), not null
|
|
# deleted_at :datetime
|
|
# duration_minutes :integer
|
|
# execute_at :datetime not null
|
|
# public_type :boolean default(TRUE)
|
|
# status_type :integer not null
|
|
# type :string default("TopicTimer"), not null
|
|
# created_at :datetime not null
|
|
# updated_at :datetime not null
|
|
# category_id :integer
|
|
# deleted_by_id :integer
|
|
# timerable_id :integer not null
|
|
# user_id :integer not null
|
|
#
|
|
# Indexes
|
|
#
|
|
# idx_timerable_id_public_type_deleted_at (timerable_id) UNIQUE WHERE ((public_type = true) AND (deleted_at IS NULL) AND ((type)::text = 'TopicTimer'::text))
|
|
# idx_topic_id_public_type_deleted_at (topic_id) UNIQUE WHERE ((public_type = true) AND (deleted_at IS NULL) AND ((type)::text = 'TopicTimer'::text))
|
|
# index_topic_timers_on_timerable_id (timerable_id) WHERE (deleted_at IS NULL)
|
|
# index_topic_timers_on_topic_id (topic_id) WHERE (deleted_at IS NULL)
|
|
# index_topic_timers_on_user_id (user_id)
|
|
#
|