2013-02-05 14:16:51 -05:00
require_dependency 'topic_view'
require_dependency 'promotion'
class TopicsController < ApplicationController
# Avatar is an image request, not XHR
2013-02-07 16:45:24 +01:00
before_filter :ensure_logged_in , only : [ :timings ,
:destroy_timings ,
:update ,
:star ,
:destroy ,
:status ,
:invite ,
:mute ,
:unmute ,
2013-02-05 14:16:51 -05:00
:set_notifications ,
2013-03-06 15:17:07 -05:00
:move_posts ,
2013-05-16 15:55:14 -04:00
:merge_topic ,
2013-05-07 14:25:41 -04:00
:clear_pin ,
:autoclose ]
2013-03-06 15:17:07 -05:00
2013-02-10 13:50:26 -05:00
before_filter :consider_user_for_promotion , only : :show
2013-02-05 14:16:51 -05:00
2013-06-06 14:41:27 -04:00
skip_before_filter :check_xhr , only : [ :avatar , :show , :feed ]
2013-03-23 20:32:59 +05:30
caches_action :avatar , cache_path : Proc . new { | c | " #{ c . params [ :post_number ] } - #{ c . params [ :topic_id ] } " }
2013-02-05 14:16:51 -05:00
2013-02-10 13:50:26 -05:00
def show
2013-05-20 10:29:49 +10:00
opts = params . slice ( :username_filters , :best_of , :page , :post_number , :posts_before , :posts_after , :best )
2013-06-06 14:41:27 -04:00
begin
@topic_view = TopicView . new ( params [ :id ] || params [ :topic_id ] , current_user , opts )
rescue Discourse :: NotFound
2013-06-07 14:17:12 -04:00
topic = Topic . where ( slug : params [ :id ] ) . first if params [ :id ]
2013-06-06 14:41:27 -04:00
raise Discourse :: NotFound unless topic
return redirect_to ( topic . relative_url )
end
2013-05-20 10:29:49 +10:00
2013-05-22 15:04:30 +10:00
raise Discourse :: NotFound if @topic_view . posts . blank? && ! ( opts [ :best ] . to_i > 0 )
2013-02-05 14:16:51 -05:00
anonymous_etag ( @topic_view . topic ) do
2013-03-05 01:42:44 +01:00
redirect_to_correct_topic && return if slugs_do_not_match
2013-02-07 16:45:24 +01:00
View . create_for ( @topic_view . topic , request . remote_ip , current_user )
2013-02-10 13:50:26 -05:00
track_visit_to_topic
perform_show_response
2013-02-05 14:16:51 -05:00
end
2013-02-13 19:04:43 +08:00
canonical_url @topic_view . canonical_path
2013-02-05 14:16:51 -05:00
end
def destroy_timings
PostTiming . destroy_for ( current_user . id , params [ :topic_id ] . to_i )
render nothing : true
end
def update
topic = Topic . where ( id : params [ :topic_id ] ) . first
2013-02-07 16:45:24 +01:00
guardian . ensure_can_edit! ( topic )
2013-02-05 14:16:51 -05:00
topic . title = params [ :title ] if params [ :title ] . present?
# TODO: we may need smarter rules about converting archetypes
2013-02-07 16:45:24 +01:00
if current_user . admin?
2013-02-05 14:16:51 -05:00
topic . archetype = " regular " if params [ :archetype ] == 'regular'
end
2013-05-31 15:22:34 -04:00
success = false
2013-02-05 14:16:51 -05:00
Topic . transaction do
2013-05-31 15:22:34 -04:00
success = topic . save
topic . change_category ( params [ :category ] ) if success
2013-02-05 14:16:51 -05:00
end
2013-04-10 11:00:50 +02:00
# this is used to return the title to the client as it may have been
# changed by "TextCleaner"
2013-05-31 15:22:34 -04:00
if success
render_serialized ( topic , BasicTopicSerializer )
else
render_json_error ( topic )
end
2013-02-05 14:16:51 -05:00
end
2013-03-14 14:45:29 -04:00
def similar_to
2013-06-06 00:14:32 -07:00
params . require ( :title )
params . require ( :raw )
2013-03-14 14:45:29 -04:00
title , raw = params [ :title ] , params [ :raw ]
raise Discourse :: InvalidParameters . new ( :title ) if title . length < SiteSetting . min_title_similar_length
raise Discourse :: InvalidParameters . new ( :raw ) if raw . length < SiteSetting . min_body_similar_length
2013-06-12 13:43:59 -04:00
topics = Topic . similar_to ( title , raw , current_user )
2013-03-14 14:45:29 -04:00
render_serialized ( topics , BasicTopicSerializer )
end
2013-02-05 14:16:51 -05:00
def status
2013-06-06 00:14:32 -07:00
params . require ( :status )
params . require ( :enabled )
2013-02-05 14:16:51 -05:00
raise Discourse :: InvalidParameters . new ( :status ) unless %w( visible closed pinned archived ) . include? ( params [ :status ] )
@topic = Topic . where ( id : params [ :topic_id ] . to_i ) . first
guardian . ensure_can_moderate! ( @topic )
@topic . update_status ( params [ :status ] , ( params [ :enabled ] == 'true' ) , current_user )
render nothing : true
end
def star
@topic = Topic . where ( id : params [ :topic_id ] . to_i ) . first
guardian . ensure_can_see! ( @topic )
@topic . toggle_star ( current_user , params [ :starred ] == 'true' )
render nothing : true
end
2013-02-07 16:45:24 +01:00
def mute
2013-06-14 11:08:59 +05:30
toggle_mute
2013-02-05 14:16:51 -05:00
end
def unmute
2013-06-14 11:08:59 +05:30
toggle_mute
2013-02-05 14:16:51 -05:00
end
2013-05-07 14:25:41 -04:00
def autoclose
2013-06-06 00:14:32 -07:00
raise Discourse :: InvalidParameters . new ( :auto_close_days ) unless params . has_key? ( :auto_close_days )
2013-05-07 14:25:41 -04:00
@topic = Topic . where ( id : params [ :topic_id ] . to_i ) . first
guardian . ensure_can_moderate! ( @topic )
2013-06-06 17:04:10 -04:00
@topic . set_auto_close ( params [ :auto_close_days ] , current_user )
2013-05-07 14:25:41 -04:00
@topic . save
render nothing : true
end
2013-02-05 14:16:51 -05:00
def destroy
topic = Topic . where ( id : params [ :id ] ) . first
guardian . ensure_can_delete! ( topic )
2013-05-07 14:39:01 +10:00
topic . trash!
2013-02-05 14:16:51 -05:00
render nothing : true
end
2013-02-07 16:45:24 +01:00
2013-02-05 14:16:51 -05:00
def excerpt
2013-02-07 16:45:24 +01:00
render nothing : true
2013-02-05 14:16:51 -05:00
end
def invite
2013-06-06 00:14:32 -07:00
params . require ( :user )
2013-02-05 14:16:51 -05:00
topic = Topic . where ( id : params [ :topic_id ] ) . first
guardian . ensure_can_invite_to! ( topic )
2013-02-07 16:45:24 +01:00
if topic . invite ( current_user , params [ :user ] )
2013-02-05 14:16:51 -05:00
render json : success_json
else
render json : failed_json , status : 422
end
end
def set_notifications
topic = Topic . find ( params [ :topic_id ] . to_i )
TopicUser . change ( current_user , topic . id , notification_level : params [ :notification_level ] . to_i )
render json : success_json
end
2013-05-16 15:55:14 -04:00
def merge_topic
2013-06-06 00:14:32 -07:00
params . require ( :destination_topic_id )
2013-05-16 15:55:14 -04:00
topic = Topic . where ( id : params [ :topic_id ] ) . first
guardian . ensure_can_move_posts! ( topic )
dest_topic = topic . move_posts ( current_user , topic . posts . pluck ( :id ) , destination_topic_id : params [ :destination_topic_id ] . to_i )
if dest_topic . present?
render json : { success : true , url : dest_topic . relative_url }
else
render json : { success : false }
end
end
2013-02-05 14:16:51 -05:00
def move_posts
2013-06-06 00:14:32 -07:00
params . require ( :post_ids )
2013-05-08 13:33:58 -04:00
2013-02-05 14:16:51 -05:00
topic = Topic . where ( id : params [ :topic_id ] ) . first
guardian . ensure_can_move_posts! ( topic )
2013-05-08 13:33:58 -04:00
args = { }
args [ :title ] = params [ :title ] if params [ :title ] . present?
args [ :destination_topic_id ] = params [ :destination_topic_id ] . to_i if params [ :destination_topic_id ] . present?
2013-02-05 14:16:51 -05:00
2013-05-08 13:33:58 -04:00
dest_topic = topic . move_posts ( current_user , params [ :post_ids ] . map { | p | p . to_i } , args )
if dest_topic . present?
render json : { success : true , url : dest_topic . relative_url }
2013-02-05 14:16:51 -05:00
else
render json : { success : false }
end
end
2013-03-06 15:17:07 -05:00
def clear_pin
topic = Topic . where ( id : params [ :topic_id ] . to_i ) . first
guardian . ensure_can_see! ( topic )
topic . clear_pin_for ( current_user )
render nothing : true
end
2013-02-25 18:38:11 -05:00
2013-03-06 15:17:07 -05:00
def timings
2013-02-25 18:42:42 +11:00
PostTiming . process_timings (
2013-03-06 15:17:07 -05:00
current_user ,
params [ :topic_id ] . to_i ,
params [ :topic_time ] . to_i ,
( params [ :timings ] || [ ] ) . map { | post_number , t | [ post_number . to_i , t . to_i ] }
2013-02-25 18:42:42 +11:00
)
2013-02-05 14:16:51 -05:00
render nothing : true
end
2013-02-21 10:20:00 -08:00
def feed
@topic_view = TopicView . new ( params [ :topic_id ] )
2013-03-01 13:56:14 -08:00
anonymous_etag ( @topic_view . topic ) do
render 'topics/show' , formats : [ :rss ]
end
2013-02-21 10:20:00 -08:00
end
2013-02-05 14:16:51 -05:00
private
2013-06-14 11:08:59 +05:30
def toggle_mute
2013-02-10 13:50:26 -05:00
@topic = Topic . where ( id : params [ :topic_id ] . to_i ) . first
guardian . ensure_can_see! ( @topic )
2013-05-23 23:06:38 -07:00
@topic . toggle_mute ( current_user )
2013-02-10 13:50:26 -05:00
render nothing : true
end
def consider_user_for_promotion
Promotion . new ( current_user ) . review if current_user . present?
end
def slugs_do_not_match
params [ :slug ] && @topic_view . topic . slug != params [ :slug ]
end
def redirect_to_correct_topic
fullpath = request . fullpath
2013-02-05 14:16:51 -05:00
2013-02-10 13:50:26 -05:00
split = fullpath . split ( '/' )
split [ 2 ] = @topic_view . topic . slug
redirect_to split . join ( '/' ) , status : 301
end
def track_visit_to_topic
return unless should_track_visit_to_topic?
TopicUser . track_visit! @topic_view . topic , current_user
@topic_view . draft = Draft . get ( current_user , @topic_view . draft_key , @topic_view . draft_sequence )
end
def should_track_visit_to_topic?
( ! request . xhr? || params [ :track_visit ] ) && current_user
end
def perform_show_response
topic_view_serializer = TopicViewSerializer . new ( @topic_view , scope : guardian , root : false )
respond_to do | format |
format . html do
store_preloaded ( " topic_ #{ @topic_view . topic . id } " , MultiJson . dump ( topic_view_serializer ) )
end
format . json do
render_json_dump ( topic_view_serializer )
end
end
end
2013-02-05 14:16:51 -05:00
end