diff --git a/app/models/topic.rb b/app/models/topic.rb index 57acf234fb1..b23b4b82eb9 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -253,29 +253,8 @@ class Topic < ActiveRecord::Base .all end - def update_status(property, status, user) - Topic.transaction do - - # Special case: if it's pinned, update that - if property.to_sym == :pinned - update_pinned(status) - else - # otherwise update the column - update_column(property == 'autoclosed' ? 'closed' : property, status) - end - - key = "topic_statuses.#{property}_" - key << (status ? 'enabled' : 'disabled') - - opts = {} - - # We don't bump moderator posts except for the re-open post. - opts[:bump] = true if (property == 'closed' or property == 'autoclosed') and (!status) - - message = property != 'autoclosed' ? I18n.t(key) : I18n.t(key, count: (((self.auto_close_at||Time.zone.now) - self.created_at) / 86_400).round ) - - add_moderator_post(user, message, opts) - end + def update_status(status, enabled, user) + TopicStatusUpdate.new(self, user).update! status, enabled end # Atomically creates the next post number diff --git a/app/models/topic_status_update.rb b/app/models/topic_status_update.rb new file mode 100644 index 00000000000..d4925b4d0eb --- /dev/null +++ b/app/models/topic_status_update.rb @@ -0,0 +1,56 @@ +TopicStatusUpdate = Struct.new(:topic, :user) do + def update!(status, enabled) + status = Status.new(status, enabled) + + Topic.transaction do + change status + create_moderator_post_for status + end + end + + private + + def change(status) + if status.pinned? + topic.update_pinned status.enabled? + elsif status.autoclosed? + topic.update_column 'closed', status.enabled? + else + topic.update_column status.name, status.enabled? + end + end + + def create_moderator_post_for(status) + topic.add_moderator_post(user, message_for(status), options_for(status)) + end + + def message_for(status) + I18n.t status.locale_key, count: topic.age_in_days + end + + def options_for(status) + { bump: status.reopening_topic? } + end + + Status = Struct.new(:name, :enabled) do + %w(pinned autoclosed closed).each do |status| + define_method("#{status}?") { name == status } + end + + def enabled? + enabled + end + + def disabled? + !enabled? + end + + def locale_key + "topic_statuses.#{name}_#{enabled? ? 'enabled' : 'disabled'}" + end + + def reopening_topic? + (closed? || autoclosed?) && disabled? + end + end +end