2015-03-26 16:57:50 -04:00
require_dependency 'has_errors'
2013-06-04 20:13:01 +02:00
2015-03-26 16:57:50 -04:00
class TopicCreator
2015-08-11 15:46:21 +10:00
attr_reader :user , :guardian , :opts
2015-03-26 16:57:50 -04:00
include HasErrors
2013-06-04 20:13:01 +02:00
2013-07-22 11:40:39 +10:00
def self . create ( user , guardian , opts )
self . new ( user , guardian , opts ) . create
end
2013-06-04 20:13:01 +02:00
def initialize ( user , guardian , opts )
@user = user
@guardian = guardian
@opts = opts
2014-09-08 11:11:56 -04:00
@added_users = [ ]
2013-06-04 20:13:01 +02:00
end
2015-03-26 16:57:50 -04:00
def valid?
topic = Topic . new ( setup_topic_params )
2015-08-11 15:46:21 +10:00
# validate? will clear the error hash
# so we fire the validation event after
# this allows us to add errors
valid = topic . valid?
2016-04-25 15:55:15 -04:00
# not sure where this should go
if ! @guardian . is_staff? && staff_only = DiscourseTagging . staff_only_tags ( @opts [ :tags ] )
topic . errors [ :base ] << I18n . t ( " tags.staff_tag_disallowed " , tag : staff_only . join ( " " ) )
end
2015-08-11 15:46:21 +10:00
DiscourseEvent . trigger ( :after_validate_topic , topic , self )
valid && = topic . errors . empty?
add_errors_from ( topic ) unless valid
valid
2015-03-26 16:57:50 -04:00
end
2013-06-04 20:13:01 +02:00
def create
2015-03-26 16:57:50 -04:00
topic = Topic . new ( setup_topic_params )
2016-05-04 14:02:47 -04:00
setup_tags ( topic )
2015-08-11 15:46:21 +10:00
DiscourseEvent . trigger ( :before_create_topic , topic , self )
2013-06-04 20:13:01 +02:00
2015-03-26 16:57:50 -04:00
setup_auto_close_time ( topic )
process_private_message ( topic )
save_topic ( topic )
create_warning ( topic )
watch_topic ( topic )
2013-07-22 11:40:39 +10:00
2015-03-26 16:57:50 -04:00
topic
2013-06-04 20:13:01 +02:00
end
private
2015-03-26 16:57:50 -04:00
def create_warning ( topic )
2014-09-08 11:11:56 -04:00
return unless @opts [ :is_warning ]
# We can only attach warnings to PMs
2015-03-26 16:57:50 -04:00
rollback_with! ( topic , :warning_requires_pm ) unless topic . private_message?
2014-09-08 11:11:56 -04:00
# Don't create it if there is more than one user
2015-03-26 16:57:50 -04:00
rollback_with! ( topic , :too_many_users ) if @added_users . size != 1
2014-09-08 11:11:56 -04:00
# Create a warning record
2015-03-26 16:57:50 -04:00
Warning . create ( topic : topic , user : @added_users . first , created_by : @user )
2014-09-08 11:11:56 -04:00
end
2015-03-26 16:57:50 -04:00
def watch_topic ( topic )
2013-07-22 11:40:39 +10:00
unless @opts [ :auto_track ] == false
2015-03-26 16:57:50 -04:00
topic . notifier . watch_topic! ( topic . user_id )
2013-07-22 11:40:39 +10:00
end
2014-01-22 17:46:52 +11:00
2015-12-14 23:17:09 +01:00
topic . topic_allowed_users ( true ) . each do | tau |
next if tau . user_id == - 1 || tau . user_id == topic . user_id
topic . notifier . watch! ( tau . user_id )
end
2014-06-24 12:31:36 -04:00
2015-12-14 23:17:09 +01:00
topic . topic_allowed_groups ( true ) . each do | tag |
tag . group . group_users . each do | gu |
next if gu . user_id == - 1 || gu . user_id == topic . user_id
action = case gu . notification_level
2016-01-27 23:20:29 +11:00
when TopicUser . notification_levels [ :tracking ] then " track! "
2015-12-14 23:17:09 +01:00
when TopicUser . notification_levels [ :regular ] then " regular! "
when TopicUser . notification_levels [ :muted ] then " mute! "
2016-01-27 23:20:29 +11:00
when TopicUser . notification_levels [ :watching ] then " watch! "
2016-01-27 21:38:14 +11:00
else " track! "
2015-12-14 23:17:09 +01:00
end
topic . notifier . send ( action , gu . user_id )
end
2014-01-22 17:46:52 +11:00
end
2013-07-22 11:40:39 +10:00
end
2014-02-06 20:52:50 +01:00
def setup_topic_params
2016-07-27 17:50:13 +08:00
@opts [ :visible ] = true if @opts [ :visible ] . nil?
2014-01-24 12:57:48 +01:00
topic_params = {
title : @opts [ :title ] ,
user_id : @user . id ,
2016-07-27 17:50:13 +08:00
last_post_user_id : @user . id ,
visible : @opts [ :visible ]
2014-01-24 12:57:48 +01:00
}
2014-07-03 14:43:24 -04:00
[ :subtype , :archetype , :meta_data , :import_mode ] . each do | key |
2014-02-06 20:52:50 +01:00
topic_params [ key ] = @opts [ key ] if @opts [ key ] . present?
2014-01-24 12:57:48 +01:00
end
2015-07-16 16:11:20 +10:00
if topic_params [ :import_mode ] && @opts [ :views ] . to_i > 0
topic_params [ :views ] = @opts [ :views ] . to_i
end
2014-09-08 13:23:40 -04:00
# Automatically give it a moderator warning subtype if specified
topic_params [ :subtype ] = TopicSubtype . moderator_warning if @opts [ :is_warning ]
2014-02-06 20:52:50 +01:00
category = find_category
2014-01-24 12:57:48 +01:00
2015-10-17 13:18:56 +05:30
@guardian . ensure_can_create! ( Topic , category ) unless ( @opts [ :skip_validations ] || @opts [ :archetype ] == Archetype . private_message )
2014-01-24 12:57:48 +01:00
2013-06-04 20:13:01 +02:00
topic_params [ :category_id ] = category . id if category . present?
2014-02-06 20:52:50 +01:00
2013-06-04 20:13:01 +02:00
topic_params [ :created_at ] = Time . zone . parse ( @opts [ :created_at ] . to_s ) if @opts [ :created_at ] . present?
2014-01-24 12:57:48 +01:00
2015-01-19 15:00:55 +01:00
topic_params [ :pinned_at ] = Time . zone . parse ( @opts [ :pinned_at ] . to_s ) if @opts [ :pinned_at ] . present?
2015-03-13 21:24:11 +01:00
topic_params [ :pinned_globally ] = @opts [ :pinned_globally ] if @opts [ :pinned_globally ] . present?
2015-01-19 15:00:55 +01:00
2013-06-04 20:13:01 +02:00
topic_params
end
2014-02-06 20:52:50 +01:00
def find_category
# PM can't have a category
@opts . delete ( :category ) if @opts [ :archetype ] . present? && @opts [ :archetype ] == Archetype . private_message
# Temporary fix to allow older clients to create topics.
# When all clients are updated the category variable should
# be set directly to the contents of the if statement.
if ( @opts [ :category ] . is_a? Integer ) || ( @opts [ :category ] =~ / ^ \ d+$ / )
2014-05-06 14:41:59 +01:00
Category . find_by ( id : @opts [ :category ] )
2014-02-06 20:52:50 +01:00
else
2014-08-18 11:07:32 -04:00
Category . find_by ( name_lower : @opts [ :category ] . try ( :downcase ) )
2014-02-06 20:52:50 +01:00
end
end
2016-05-04 14:02:47 -04:00
def setup_tags ( topic )
DiscourseTagging . tag_topic_by_names ( topic , @guardian , @opts [ :tags ] )
end
2015-03-26 16:57:50 -04:00
def setup_auto_close_time ( topic )
2014-02-06 20:52:50 +01:00
return unless @opts [ :auto_close_time ] . present?
2015-03-26 16:57:50 -04:00
return unless @guardian . can_moderate? ( topic )
2015-05-27 12:22:34 -04:00
topic . set_auto_close ( @opts [ :auto_close_time ] , { by_user : @user } )
2013-06-04 20:13:01 +02:00
end
2015-03-26 16:57:50 -04:00
def process_private_message ( topic )
2014-02-06 20:52:50 +01:00
return unless @opts [ :archetype ] == Archetype . private_message
2015-03-26 16:57:50 -04:00
topic . subtype = TopicSubtype . user_to_user unless topic . subtype
2013-06-04 20:13:01 +02:00
unless @opts [ :target_usernames ] . present? || @opts [ :target_group_names ] . present?
2015-03-26 16:57:50 -04:00
rollback_with! ( topic , :no_user_selected )
2013-06-04 20:13:01 +02:00
end
2015-03-26 16:57:50 -04:00
add_users ( topic , @opts [ :target_usernames ] )
add_groups ( topic , @opts [ :target_group_names ] )
topic . topic_allowed_users . build ( user_id : @user . id )
2013-06-04 20:13:01 +02:00
end
2015-03-26 16:57:50 -04:00
def save_topic ( topic )
2015-04-21 16:48:39 -04:00
topic . disable_rate_limits! if @opts [ :skip_validations ]
2015-03-26 16:57:50 -04:00
unless topic . save ( validate : ! @opts [ :skip_validations ] )
rollback_from_errors! ( topic )
2013-06-04 20:13:01 +02:00
end
end
def add_users ( topic , usernames )
return unless usernames
2015-12-02 15:49:43 +11:00
names = usernames . split ( ',' ) . flatten
len = 0
User . where ( username : names ) . each do | user |
2014-09-08 11:11:56 -04:00
check_can_send_permission! ( topic , user )
@added_users << user
2013-06-04 20:13:01 +02:00
topic . topic_allowed_users . build ( user_id : user . id )
2015-12-02 15:49:43 +11:00
len += 1
2013-06-04 20:13:01 +02:00
end
2015-12-02 15:49:43 +11:00
rollback_with! ( topic , :target_user_not_found ) unless len == names . length
2013-06-04 20:13:01 +02:00
end
def add_groups ( topic , groups )
return unless groups
2015-12-07 17:01:08 +01:00
names = groups . split ( ',' ) . flatten
2015-12-02 15:49:43 +11:00
len = 0
Group . where ( name : names ) . each do | group |
2015-03-26 16:57:50 -04:00
check_can_send_permission! ( topic , group )
2013-06-04 20:13:01 +02:00
topic . topic_allowed_groups . build ( group_id : group . id )
2015-12-02 15:49:43 +11:00
len += 1
2015-12-20 17:21:31 +11:00
group . update_columns ( has_messages : true ) unless group . has_messages
2013-06-04 20:13:01 +02:00
end
2015-12-02 15:49:43 +11:00
rollback_with! ( topic , :target_group_not_found ) unless len == names . length
2013-06-04 20:13:01 +02:00
end
2015-03-26 16:57:50 -04:00
def check_can_send_permission! ( topic , obj )
2016-01-19 00:57:55 +01:00
rollback_with! ( topic , :cant_send_pm ) unless @opts [ :skip_validations ] || @guardian . can_send_private_message? ( obj )
2013-06-04 20:13:01 +02:00
end
end