2013-02-05 14:16:51 -05:00
|
|
|
require_dependency 'topic_view'
|
|
|
|
require_dependency 'promotion'
|
2013-12-12 11:24:00 -05:00
|
|
|
require_dependency 'url_helper'
|
2014-01-30 11:15:49 -05:00
|
|
|
require_dependency 'topics_bulk_action'
|
2015-01-02 15:56:44 -05:00
|
|
|
require_dependency 'discourse_event'
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
class TopicsController < ApplicationController
|
2013-02-07 10:45:24 -05:00
|
|
|
before_filter :ensure_logged_in, only: [:timings,
|
|
|
|
:destroy_timings,
|
|
|
|
:update,
|
|
|
|
:star,
|
|
|
|
:destroy,
|
2013-07-12 12:08:23 -04:00
|
|
|
:recover,
|
2013-02-07 10:45:24 -05:00
|
|
|
: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,
|
2014-04-09 20:56:56 -04:00
|
|
|
:re_pin,
|
2014-01-29 15:48:52 -05:00
|
|
|
:autoclose,
|
2014-03-03 15:46:38 -05:00
|
|
|
:bulk,
|
2014-03-27 21:28:14 -04:00
|
|
|
:reset_new,
|
2015-01-12 06:10:15 -05:00
|
|
|
:change_post_owners,
|
2015-07-25 12:06:49 -04:00
|
|
|
:change_timestamps,
|
2015-12-29 21:26:21 -05:00
|
|
|
:archive_message,
|
|
|
|
:move_to_inbox,
|
2016-05-01 07:48:43 -04:00
|
|
|
:convert_topic,
|
2015-11-11 01:23:24 -05:00
|
|
|
:bookmark]
|
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
|
|
|
|
2015-08-12 17:00:16 -04:00
|
|
|
skip_before_filter :check_xhr, only: [:show, :unsubscribe, :feed]
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2014-09-17 11:18:41 -04:00
|
|
|
def id_for_slug
|
|
|
|
topic = Topic.find_by(slug: params[:slug].downcase)
|
|
|
|
guardian.ensure_can_see!(topic)
|
|
|
|
raise Discourse::NotFound unless topic
|
|
|
|
render json: {slug: topic.slug, topic_id: topic.id, url: topic.url}
|
|
|
|
end
|
|
|
|
|
2013-02-10 13:50:26 -05:00
|
|
|
def show
|
2015-04-22 12:41:28 -04:00
|
|
|
if request.referer
|
|
|
|
flash["referer"] ||= request.referer[0..255]
|
|
|
|
end
|
2014-08-03 21:06:06 -04:00
|
|
|
|
2013-06-28 13:55:34 -04:00
|
|
|
# We'd like to migrate the wordpress feed to another url. This keeps up backwards compatibility with
|
|
|
|
# existing installs.
|
|
|
|
return wordpress if params[:best].present?
|
|
|
|
|
2016-02-24 22:32:16 -05:00
|
|
|
# work around people somehow sending in arrays,
|
|
|
|
# arrays are not supported
|
|
|
|
params[:page] = params[:page].to_i rescue 1
|
|
|
|
|
2014-07-15 17:02:43 -04:00
|
|
|
opts = params.slice(:username_filters, :filter, :page, :post_number, :show_deleted)
|
2013-10-28 02:12:07 -04:00
|
|
|
username_filters = opts[:username_filters]
|
2013-09-16 14:08:55 -04:00
|
|
|
|
2014-12-15 11:54:26 -05:00
|
|
|
opts[:slow_platform] = true if slow_platform?
|
2016-08-01 00:45:05 -04:00
|
|
|
opts[:print] = true if params[:print].present?
|
2014-04-15 15:33:08 -04:00
|
|
|
opts[:username_filters] = username_filters.split(',') if username_filters.is_a?(String)
|
2013-10-03 12:51:30 -04:00
|
|
|
|
2016-09-19 13:31:19 -04:00
|
|
|
# Special case: a slug with a number in front should look by slug first before looking
|
|
|
|
# up that particular number
|
|
|
|
if params[:id] && params[:id] =~ /^\d+[^\d\\]+$/
|
|
|
|
topic = Topic.find_by(slug: params[:id].downcase)
|
|
|
|
return redirect_to_correct_topic(topic, opts[:post_number]) if topic && topic.visible
|
|
|
|
end
|
|
|
|
|
2013-06-06 14:41:27 -04:00
|
|
|
begin
|
|
|
|
@topic_view = TopicView.new(params[:id] || params[:topic_id], current_user, opts)
|
|
|
|
rescue Discourse::NotFound
|
2015-01-05 11:02:32 -05:00
|
|
|
if params[:id]
|
|
|
|
topic = Topic.find_by(slug: params[:id].downcase)
|
2016-06-09 20:53:03 -04:00
|
|
|
return redirect_to_correct_topic(topic, opts[:post_number]) if topic && topic.visible
|
2015-01-05 11:02:32 -05:00
|
|
|
end
|
|
|
|
raise Discourse::NotFound
|
2013-06-06 14:41:27 -04:00
|
|
|
end
|
2013-05-19 20:29:49 -04:00
|
|
|
|
2016-02-24 22:32:16 -05:00
|
|
|
page = params[:page]
|
2014-12-12 11:47:20 -05:00
|
|
|
if (page < 0) || ((page - 1) * @topic_view.chunk_size > @topic_view.topic.highest_post_number)
|
2014-09-22 03:08:11 -04:00
|
|
|
raise Discourse::NotFound
|
|
|
|
end
|
|
|
|
|
2013-10-16 01:39:18 -04:00
|
|
|
discourse_expires_in 1.minute
|
2013-07-04 14:08:23 -04:00
|
|
|
|
2016-06-12 02:36:38 -04:00
|
|
|
if !@topic_view.topic.visible && @topic_view.topic.slug != params[:slug] && !request.format.json?
|
2016-06-09 20:53:03 -04:00
|
|
|
raise Discourse::NotFound
|
|
|
|
end
|
|
|
|
|
|
|
|
if slugs_do_not_match || (!request.format.json? && params[:slug].nil?)
|
|
|
|
redirect_to_correct_topic(@topic_view.topic, opts[:post_number])
|
|
|
|
return
|
|
|
|
end
|
2013-07-04 14:08:23 -04:00
|
|
|
|
2013-10-16 01:39:18 -04:00
|
|
|
track_visit_to_topic
|
2013-10-04 03:00:23 -04:00
|
|
|
|
2013-10-16 01:39:18 -04:00
|
|
|
if should_track_visit_to_topic?
|
|
|
|
@topic_view.draft = Draft.get(current_user, @topic_view.draft_key, @topic_view.draft_sequence)
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
2015-06-22 14:00:39 -04:00
|
|
|
|
|
|
|
unless @topic_view.topic.visible
|
|
|
|
response.headers['X-Robots-Tag'] = 'noindex'
|
|
|
|
end
|
2013-02-13 06:04:43 -05:00
|
|
|
|
2015-10-01 12:24:07 -04:00
|
|
|
canonical_url UrlHelper.absolute_without_cdn(@topic_view.canonical_path)
|
2015-09-21 19:37:23 -04:00
|
|
|
|
2013-10-16 01:39:18 -04:00
|
|
|
perform_show_response
|
|
|
|
|
2014-05-26 13:26:28 -04:00
|
|
|
rescue Discourse::InvalidAccess => ex
|
|
|
|
|
|
|
|
if current_user
|
|
|
|
# If the user can't see the topic, clean up notifications for it.
|
|
|
|
Notification.remove_for(current_user.id, params[:topic_id])
|
|
|
|
end
|
|
|
|
|
2015-09-18 03:14:10 -04:00
|
|
|
if ex.obj && Topic === ex.obj && guardian.can_see_topic_if_not_deleted?(ex.obj)
|
|
|
|
rescue_discourse_actions(:not_found, 410)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2014-05-26 13:26:28 -04:00
|
|
|
raise ex
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2015-08-12 17:00:16 -04:00
|
|
|
def unsubscribe
|
2015-11-11 01:23:24 -05:00
|
|
|
if current_user.blank?
|
|
|
|
cookies[:destination_url] = request.fullpath
|
|
|
|
return redirect_to "/login-preferences"
|
|
|
|
end
|
|
|
|
|
2015-08-12 17:00:16 -04:00
|
|
|
@topic_view = TopicView.new(params[:topic_id], current_user)
|
|
|
|
|
|
|
|
if slugs_do_not_match || (!request.format.json? && params[:slug].blank?)
|
|
|
|
return redirect_to @topic_view.topic.unsubscribe_url, status: 301
|
|
|
|
end
|
|
|
|
|
|
|
|
tu = TopicUser.find_by(user_id: current_user.id, topic_id: params[:topic_id])
|
|
|
|
|
2016-04-24 21:24:52 -04:00
|
|
|
if tu && tu.notification_level > TopicUser.notification_levels[:regular]
|
2015-08-12 17:00:16 -04:00
|
|
|
tu.notification_level = TopicUser.notification_levels[:regular]
|
2016-04-24 21:24:52 -04:00
|
|
|
tu.save!
|
2015-08-12 17:00:16 -04:00
|
|
|
else
|
2016-04-24 21:24:52 -04:00
|
|
|
TopicUser.change(current_user.id, params[:topic_id].to_i, notification_level: TopicUser.notification_levels[:muted])
|
2015-08-12 17:00:16 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
perform_show_response
|
|
|
|
end
|
|
|
|
|
2013-06-28 13:55:34 -04:00
|
|
|
def wordpress
|
|
|
|
params.require(:best)
|
|
|
|
params.require(:topic_id)
|
2013-07-05 16:07:24 -04:00
|
|
|
params.permit(:min_trust_level, :min_score, :min_replies, :bypass_trust_level_score, :only_moderator_liked)
|
2014-06-16 12:28:07 -04:00
|
|
|
|
2013-10-28 02:12:07 -04:00
|
|
|
opts = { best: params[:best].to_i,
|
2014-08-19 20:15:24 -04:00
|
|
|
min_trust_level: params[:min_trust_level] ? params[:min_trust_level].to_i : 1,
|
2013-10-28 02:12:07 -04:00
|
|
|
min_score: params[:min_score].to_i,
|
|
|
|
min_replies: params[:min_replies].to_i,
|
|
|
|
bypass_trust_level_score: params[:bypass_trust_level_score].to_i, # safe cause 0 means ignore
|
|
|
|
only_moderator_liked: params[:only_moderator_liked].to_s == "true"
|
|
|
|
}
|
|
|
|
|
|
|
|
@topic_view = TopicView.new(params[:topic_id], current_user, opts)
|
2013-10-16 01:39:18 -04:00
|
|
|
discourse_expires_in 1.minute
|
|
|
|
|
|
|
|
wordpress_serializer = TopicViewWordpressSerializer.new(@topic_view, scope: guardian, root: false)
|
|
|
|
render_json_dump(wordpress_serializer)
|
2013-06-20 17:20:08 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def posts
|
|
|
|
params.require(:topic_id)
|
2016-04-05 13:12:14 -04:00
|
|
|
params.permit(:post_ids)
|
2013-06-28 13:55:34 -04:00
|
|
|
|
2013-06-20 17:20:08 -04:00
|
|
|
@topic_view = TopicView.new(params[:topic_id], current_user, post_ids: params[:post_ids])
|
2014-11-07 10:28:07 -05:00
|
|
|
render_json_dump(TopicViewPostsSerializer.new(@topic_view, scope: guardian, root: false, include_raw: !!params[:include_raw]))
|
2013-06-28 13:55:34 -04:00
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def destroy_timings
|
2014-02-21 13:03:50 -05:00
|
|
|
PostTiming.destroy_for(current_user.id, [params[:topic_id].to_i])
|
2013-02-05 14:16:51 -05:00
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
|
|
|
def update
|
2014-05-06 09:41:59 -04:00
|
|
|
topic = Topic.find_by(id: params[:topic_id])
|
2013-02-07 10:45:24 -05:00
|
|
|
guardian.ensure_can_edit!(topic)
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2014-10-27 17:06:43 -04:00
|
|
|
changes = {}
|
2015-04-18 07:53:53 -04:00
|
|
|
PostRevisor.tracked_topic_fields.each_key do |f|
|
2015-01-27 12:13:45 -05:00
|
|
|
changes[f] = params[f] if params.has_key?(f)
|
|
|
|
end
|
2014-10-27 17:06:43 -04:00
|
|
|
|
2015-01-27 12:13:45 -05:00
|
|
|
changes.delete(:title) if topic.title == changes[:title]
|
2015-02-17 18:35:52 -05:00
|
|
|
changes.delete(:category_id) if topic.category_id.to_i == changes[:category_id].to_i
|
2014-10-27 17:06:43 -04:00
|
|
|
|
2015-01-27 12:13:45 -05:00
|
|
|
success = true
|
2014-10-27 17:06:43 -04:00
|
|
|
if changes.length > 0
|
|
|
|
first_post = topic.ordered_posts.first
|
2014-11-17 10:06:43 -05:00
|
|
|
success = PostRevisor.new(first_post, topic).revise!(current_user, changes, validate_post: false)
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
2013-12-11 21:41:34 -05:00
|
|
|
|
|
|
|
# this is used to return the title to the client as it may have been changed by "TextCleaner"
|
2013-10-28 02:12:07 -04:00
|
|
|
success ? render_serialized(topic, BasicTopicSerializer) : render_json_error(topic)
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2015-03-13 20:18:05 -04:00
|
|
|
def feature_stats
|
|
|
|
params.require(:category_id)
|
|
|
|
category_id = params[:category_id].to_i
|
|
|
|
|
2015-06-22 08:08:30 -04:00
|
|
|
visible_topics = Topic.listable_topics.visible
|
2015-03-13 20:18:05 -04:00
|
|
|
|
|
|
|
render json: {
|
2015-06-22 08:08:30 -04:00
|
|
|
pinned_in_category_count: visible_topics.where(category_id: category_id).where(pinned_globally: false).where.not(pinned_at: nil).count,
|
|
|
|
pinned_globally_count: visible_topics.where(pinned_globally: true).where.not(pinned_at: nil).count,
|
|
|
|
banner_count: Topic.listable_topics.where(archetype: Archetype.banner).count,
|
2015-03-13 20:18:05 -04:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def status
|
2013-06-06 03:14:32 -04:00
|
|
|
params.require(:status)
|
|
|
|
params.require(:enabled)
|
2015-07-29 10:34:21 -04:00
|
|
|
params.permit(:until)
|
|
|
|
|
|
|
|
status = params[:status]
|
|
|
|
topic_id = params[:topic_id].to_i
|
|
|
|
enabled = params[:enabled] == 'true'
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2013-10-28 02:12:07 -04:00
|
|
|
check_for_status_presence(:status, status)
|
2014-05-06 09:41:59 -04:00
|
|
|
@topic = Topic.find_by(id: topic_id)
|
2013-02-05 14:16:51 -05:00
|
|
|
guardian.ensure_can_moderate!(@topic)
|
2015-07-29 10:34:21 -04:00
|
|
|
@topic.update_status(status, enabled, current_user, until: params[:until])
|
2013-02-05 14:16:51 -05:00
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
2013-02-07 10:45:24 -05:00
|
|
|
def mute
|
2013-06-14 01:38:59 -04:00
|
|
|
toggle_mute
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def unmute
|
2013-06-14 01:38:59 -04:00
|
|
|
toggle_mute
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2013-05-07 14:25:41 -04:00
|
|
|
def autoclose
|
2015-05-27 12:22:34 -04:00
|
|
|
params.permit(:auto_close_time, :timezone_offset)
|
2014-10-10 12:21:44 -04:00
|
|
|
params.require(:auto_close_based_on_last_post)
|
|
|
|
|
2014-05-06 09:41:59 -04:00
|
|
|
topic = Topic.find_by(id: params[:topic_id].to_i)
|
2013-11-26 19:06:20 -05:00
|
|
|
guardian.ensure_can_moderate!(topic)
|
2014-10-10 12:21:44 -04:00
|
|
|
|
|
|
|
topic.auto_close_based_on_last_post = params[:auto_close_based_on_last_post]
|
2015-05-27 12:22:34 -04:00
|
|
|
topic.set_auto_close(params[:auto_close_time], {by_user: current_user, timezone_offset: params[:timezone_offset] ? params[:timezone_offset].to_i : nil})
|
2014-10-10 12:21:44 -04:00
|
|
|
|
2013-11-26 19:06:20 -05:00
|
|
|
if topic.save
|
2014-10-10 12:21:44 -04:00
|
|
|
render json: success_json.merge!({
|
|
|
|
auto_close_at: topic.auto_close_at,
|
|
|
|
auto_close_hours: topic.auto_close_hours
|
|
|
|
})
|
2013-11-26 19:06:20 -05:00
|
|
|
else
|
|
|
|
render_json_error(topic)
|
|
|
|
end
|
2013-05-07 14:25:41 -04:00
|
|
|
end
|
|
|
|
|
2014-06-16 12:28:07 -04:00
|
|
|
def make_banner
|
|
|
|
topic = Topic.find_by(id: params[:topic_id].to_i)
|
|
|
|
guardian.ensure_can_moderate!(topic)
|
|
|
|
|
2014-06-16 13:21:21 -04:00
|
|
|
topic.make_banner!(current_user)
|
2014-06-16 12:28:07 -04:00
|
|
|
|
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
|
|
|
def remove_banner
|
|
|
|
topic = Topic.find_by(id: params[:topic_id].to_i)
|
|
|
|
guardian.ensure_can_moderate!(topic)
|
|
|
|
|
2014-06-16 13:21:21 -04:00
|
|
|
topic.remove_banner!(current_user)
|
2014-06-16 12:28:07 -04:00
|
|
|
|
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
2015-02-18 18:58:57 -05:00
|
|
|
def remove_bookmarks
|
|
|
|
topic = Topic.find(params[:topic_id].to_i)
|
|
|
|
|
|
|
|
PostAction.joins(:post)
|
|
|
|
.where(user_id: current_user.id)
|
|
|
|
.where('topic_id = ?', topic.id).each do |pa|
|
|
|
|
|
|
|
|
PostAction.remove_act(current_user, pa.post, PostActionType.types[:bookmark])
|
|
|
|
end
|
|
|
|
|
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
2015-12-29 21:26:21 -05:00
|
|
|
def archive_message
|
|
|
|
toggle_archive_message(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
def move_to_inbox
|
|
|
|
toggle_archive_message(false)
|
|
|
|
end
|
|
|
|
|
|
|
|
def toggle_archive_message(archive)
|
|
|
|
topic = Topic.find(params[:id].to_i)
|
2016-01-11 23:49:05 -05:00
|
|
|
|
|
|
|
group_id = nil
|
|
|
|
|
2015-12-29 21:26:21 -05:00
|
|
|
group_ids = current_user.groups.pluck(:id)
|
|
|
|
if group_ids.present?
|
|
|
|
allowed_groups = topic.allowed_groups
|
|
|
|
.where('topic_allowed_groups.group_id IN (?)', group_ids).pluck(:id)
|
|
|
|
allowed_groups.each do |id|
|
|
|
|
if archive
|
2016-02-07 07:39:07 -05:00
|
|
|
GroupArchivedMessage.archive!(id, topic.id)
|
2016-01-11 23:49:05 -05:00
|
|
|
group_id = id
|
2016-02-07 07:39:07 -05:00
|
|
|
else
|
|
|
|
GroupArchivedMessage.move_to_inbox!(id, topic.id)
|
2015-12-29 21:26:21 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if topic.allowed_users.include?(current_user)
|
|
|
|
if archive
|
2016-02-07 07:39:07 -05:00
|
|
|
UserArchivedMessage.archive!(current_user.id, topic.id)
|
|
|
|
else
|
|
|
|
UserArchivedMessage.move_to_inbox!(current_user.id, topic.id)
|
2015-12-29 21:26:21 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-01-11 23:49:05 -05:00
|
|
|
if group_id
|
|
|
|
name = Group.find_by(id: group_id).try(:name)
|
|
|
|
render_json_dump(group_name: name)
|
|
|
|
else
|
|
|
|
render nothing: true
|
|
|
|
end
|
2015-12-29 21:26:21 -05:00
|
|
|
end
|
|
|
|
|
2015-01-12 06:10:15 -05:00
|
|
|
def bookmark
|
2015-02-18 18:58:57 -05:00
|
|
|
topic = Topic.find(params[:topic_id].to_i)
|
2015-01-12 06:10:15 -05:00
|
|
|
first_post = topic.ordered_posts.first
|
|
|
|
|
2015-02-18 18:58:57 -05:00
|
|
|
PostAction.act(current_user, first_post, PostActionType.types[:bookmark])
|
2015-01-12 06:10:15 -05:00
|
|
|
|
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def destroy
|
2014-05-06 09:41:59 -04:00
|
|
|
topic = Topic.find_by(id: params[:id])
|
2013-02-05 14:16:51 -05:00
|
|
|
guardian.ensure_can_delete!(topic)
|
2014-08-07 13:12:35 -04:00
|
|
|
|
|
|
|
first_post = topic.ordered_posts.first
|
2014-10-01 11:40:13 -04:00
|
|
|
PostDestroyer.new(current_user, first_post, { context: params[:context] }).destroy
|
2014-08-07 13:12:35 -04:00
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
render nothing: true
|
|
|
|
end
|
2013-02-07 10:45:24 -05:00
|
|
|
|
2013-07-12 12:08:23 -04:00
|
|
|
def recover
|
|
|
|
topic = Topic.where(id: params[:topic_id]).with_deleted.first
|
|
|
|
guardian.ensure_can_recover_topic!(topic)
|
2014-08-07 13:12:35 -04:00
|
|
|
|
|
|
|
first_post = topic.posts.with_deleted.order(:post_number).first
|
|
|
|
PostDestroyer.new(current_user, first_post).recover
|
|
|
|
|
2013-07-12 12:08:23 -04:00
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def excerpt
|
2013-02-07 10:45:24 -05:00
|
|
|
render nothing: true
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2013-06-18 03:17:01 -04:00
|
|
|
def remove_allowed_user
|
|
|
|
params.require(:username)
|
2014-05-06 09:41:59 -04:00
|
|
|
topic = Topic.find_by(id: params[:topic_id])
|
2013-06-18 03:17:01 -04:00
|
|
|
guardian.ensure_can_remove_allowed_users!(topic)
|
|
|
|
|
2016-01-11 06:42:06 -05:00
|
|
|
if topic.remove_allowed_user(current_user, params[:username])
|
2013-06-18 03:17:01 -04:00
|
|
|
render json: success_json
|
|
|
|
else
|
|
|
|
render json: failed_json, status: 422
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-06-20 02:29:11 -04:00
|
|
|
def remove_allowed_group
|
|
|
|
params.require(:name)
|
|
|
|
topic = Topic.find_by(id: params[:topic_id])
|
|
|
|
guardian.ensure_can_remove_allowed_users!(topic)
|
|
|
|
|
|
|
|
if topic.remove_allowed_group(current_user, params[:name])
|
|
|
|
render json: success_json
|
|
|
|
else
|
|
|
|
render json: failed_json, status: 422
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def invite_group
|
|
|
|
group = Group.find_by(name: params[:group])
|
|
|
|
raise Discourse::NotFound unless group
|
|
|
|
|
|
|
|
topic = Topic.find_by(id: params[:topic_id])
|
|
|
|
|
|
|
|
if topic.private_message?
|
|
|
|
guardian.ensure_can_send_private_message!(group)
|
|
|
|
topic.invite_group(current_user, group)
|
2016-06-21 02:01:29 -04:00
|
|
|
render_json_dump BasicGroupSerializer.new(group, scope: guardian, root: 'group')
|
2016-06-20 02:29:11 -04:00
|
|
|
else
|
|
|
|
render json: failed_json, status: 422
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def invite
|
2013-10-28 02:12:07 -04:00
|
|
|
username_or_email = params[:user] ? fetch_username : fetch_email
|
2013-07-10 21:21:39 -04:00
|
|
|
|
2014-05-06 09:41:59 -04:00
|
|
|
topic = Topic.find_by(id: params[:topic_id])
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2014-05-09 04:22:15 -04:00
|
|
|
group_ids = Group.lookup_group_ids(params)
|
2014-05-08 21:45:18 -04:00
|
|
|
guardian.ensure_can_invite_to!(topic,group_ids)
|
|
|
|
|
2015-12-14 11:02:23 -05:00
|
|
|
begin
|
2016-06-07 13:24:45 -04:00
|
|
|
if topic.invite(current_user, username_or_email, group_ids, params[:custom_message])
|
2015-12-14 11:02:23 -05:00
|
|
|
user = User.find_by_username_or_email(username_or_email)
|
|
|
|
if user
|
|
|
|
render_json_dump BasicUserSerializer.new(user, scope: guardian, root: 'user')
|
|
|
|
else
|
|
|
|
render json: success_json
|
|
|
|
end
|
2013-06-18 03:17:01 -04:00
|
|
|
else
|
2015-12-14 11:02:23 -05:00
|
|
|
render json: failed_json, status: 422
|
2013-06-18 03:17:01 -04:00
|
|
|
end
|
2015-12-14 11:02:23 -05:00
|
|
|
rescue => e
|
|
|
|
render json: {errors: [e.message]}, status: 422
|
2013-02-05 14:16:51 -05:00
|
|
|
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 03:14:32 -04:00
|
|
|
params.require(:destination_topic_id)
|
2013-05-16 15:55:14 -04:00
|
|
|
|
2014-05-06 09:41:59 -04:00
|
|
|
topic = Topic.find_by(id: params[:topic_id])
|
2013-05-16 15:55:14 -04:00
|
|
|
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)
|
2013-06-18 01:52:09 -04:00
|
|
|
render_topic_changes(dest_topic)
|
2013-05-16 15:55:14 -04:00
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def move_posts
|
2013-06-06 03:14:32 -04:00
|
|
|
params.require(:post_ids)
|
2013-10-29 15:30:06 -04:00
|
|
|
params.require(:topic_id)
|
|
|
|
params.permit(:category_id)
|
2013-05-08 13:33:58 -04:00
|
|
|
|
2014-05-06 09:41:59 -04:00
|
|
|
topic = Topic.find_by(id: params[:topic_id])
|
2013-02-05 14:16:51 -05:00
|
|
|
guardian.ensure_can_move_posts!(topic)
|
|
|
|
|
2013-09-04 11:53:00 -04:00
|
|
|
dest_topic = move_posts_to_destination(topic)
|
2013-06-18 01:52:09 -04:00
|
|
|
render_topic_changes(dest_topic)
|
2014-08-11 14:42:50 -04:00
|
|
|
rescue ActiveRecord::RecordInvalid => ex
|
|
|
|
render_json_error(ex)
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2014-03-27 21:28:14 -04:00
|
|
|
def change_post_owners
|
|
|
|
params.require(:post_ids)
|
|
|
|
params.require(:topic_id)
|
|
|
|
params.require(:username)
|
|
|
|
|
|
|
|
guardian.ensure_can_change_post_owner!
|
|
|
|
|
2015-03-02 11:17:11 -05:00
|
|
|
begin
|
|
|
|
PostOwnerChanger.new( post_ids: params[:post_ids].to_a,
|
|
|
|
topic_id: params[:topic_id].to_i,
|
|
|
|
new_owner: User.find_by(username: params[:username]),
|
|
|
|
acting_user: current_user ).change_owner!
|
|
|
|
render json: success_json
|
|
|
|
rescue ArgumentError
|
|
|
|
render json: failed_json, status: 422
|
2014-03-27 21:28:14 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-07-25 12:06:49 -04:00
|
|
|
def change_timestamps
|
|
|
|
params.require(:topic_id)
|
|
|
|
params.require(:timestamp)
|
|
|
|
|
|
|
|
guardian.ensure_can_change_post_owner!
|
|
|
|
|
|
|
|
begin
|
|
|
|
PostTimestampChanger.new( topic_id: params[:topic_id].to_i,
|
|
|
|
timestamp: params[:timestamp].to_i ).change!
|
|
|
|
|
|
|
|
render json: success_json
|
|
|
|
rescue ActiveRecord::RecordInvalid
|
|
|
|
render json: failed_json, status: 422
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-03-06 15:17:07 -05:00
|
|
|
def clear_pin
|
2014-05-06 09:41:59 -04:00
|
|
|
topic = Topic.find_by(id: params[:topic_id].to_i)
|
2013-03-06 15:17:07 -05:00
|
|
|
guardian.ensure_can_see!(topic)
|
|
|
|
topic.clear_pin_for(current_user)
|
|
|
|
render nothing: true
|
|
|
|
end
|
2013-02-25 18:38:11 -05:00
|
|
|
|
2014-04-09 20:56:56 -04:00
|
|
|
def re_pin
|
2014-05-06 09:41:59 -04:00
|
|
|
topic = Topic.find_by(id: params[:topic_id].to_i)
|
2014-04-09 20:56:56 -04:00
|
|
|
guardian.ensure_can_see!(topic)
|
|
|
|
topic.re_pin_for(current_user)
|
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
2013-03-06 15:17:07 -05:00
|
|
|
def timings
|
2013-02-25 02:42:42 -05:00
|
|
|
PostTiming.process_timings(
|
2013-03-06 15:17:07 -05:00
|
|
|
current_user,
|
|
|
|
params[:topic_id].to_i,
|
|
|
|
params[:topic_time].to_i,
|
2015-07-07 12:31:07 -04:00
|
|
|
(params[:timings] || []).map{|post_number, t| [post_number.to_i, t.to_i]},
|
|
|
|
{mobile: view_context.mobile_view?}
|
2013-02-25 02:42:42 -05:00
|
|
|
)
|
2013-02-05 14:16:51 -05:00
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
2013-02-21 13:20:00 -05:00
|
|
|
def feed
|
|
|
|
@topic_view = TopicView.new(params[:topic_id])
|
2013-10-16 01:39:18 -04:00
|
|
|
discourse_expires_in 1.minute
|
|
|
|
render 'topics/show', formats: [:rss]
|
2013-02-21 13:20:00 -05:00
|
|
|
end
|
|
|
|
|
2014-01-29 15:48:52 -05:00
|
|
|
def bulk
|
2014-02-21 14:17:45 -05:00
|
|
|
if params[:topic_ids].present?
|
|
|
|
topic_ids = params[:topic_ids].map {|t| t.to_i}
|
|
|
|
elsif params[:filter] == 'unread'
|
|
|
|
tq = TopicQuery.new(current_user)
|
2014-10-30 10:19:49 -04:00
|
|
|
topics = TopicQuery.unread_filter(tq.joined_topic_user).listable_topics
|
|
|
|
topics = topics.where('category_id = ?', params[:category_id]) if params[:category_id]
|
|
|
|
topic_ids = topics.pluck(:id)
|
2014-02-21 14:17:45 -05:00
|
|
|
else
|
|
|
|
raise ActionController::ParameterMissing.new(:topic_ids)
|
|
|
|
end
|
|
|
|
|
2014-01-30 11:15:49 -05:00
|
|
|
operation = params.require(:operation).symbolize_keys
|
|
|
|
raise ActionController::ParameterMissing.new(:operation_type) if operation[:type].blank?
|
2015-12-22 19:09:17 -05:00
|
|
|
operator = TopicsBulkAction.new(current_user, topic_ids, operation, group: operation[:group])
|
2014-01-30 11:15:49 -05:00
|
|
|
changed_topic_ids = operator.perform!
|
|
|
|
render_json_dump topic_ids: changed_topic_ids
|
2014-01-29 15:48:52 -05:00
|
|
|
end
|
|
|
|
|
2014-03-03 15:46:38 -05:00
|
|
|
def reset_new
|
|
|
|
current_user.user_stat.update_column(:new_since, Time.now)
|
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
2016-05-01 07:48:43 -04:00
|
|
|
def convert_topic
|
|
|
|
params.require(:id)
|
|
|
|
params.require(:type)
|
|
|
|
topic = Topic.find_by(id: params[:id])
|
|
|
|
guardian.ensure_can_convert_topic!(topic)
|
|
|
|
|
|
|
|
if params[:type] == "public"
|
|
|
|
converted_topic = topic.convert_to_public_topic(current_user)
|
|
|
|
else
|
|
|
|
converted_topic = topic.convert_to_private_message(current_user)
|
|
|
|
end
|
|
|
|
render_topic_changes(converted_topic)
|
|
|
|
rescue ActiveRecord::RecordInvalid => ex
|
|
|
|
render_json_error(ex)
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
private
|
|
|
|
|
2013-06-14 01:38:59 -04:00
|
|
|
def toggle_mute
|
2014-05-06 09:41:59 -04:00
|
|
|
@topic = Topic.find_by(id: params[:topic_id].to_i)
|
2013-02-10 13:50:26 -05:00
|
|
|
guardian.ensure_can_see!(@topic)
|
|
|
|
|
2013-05-24 02:06:38 -04: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
|
|
|
|
|
2014-08-13 16:12:44 -04:00
|
|
|
def redirect_to_correct_topic(topic, post_number=nil)
|
|
|
|
url = topic.relative_url
|
2014-08-17 22:35:31 -04:00
|
|
|
url << "/#{post_number}" if post_number.to_i > 0
|
2014-08-13 16:12:44 -04:00
|
|
|
url << ".json" if request.format.json?
|
|
|
|
|
2016-02-24 22:32:16 -05:00
|
|
|
page = params[:page]
|
2015-05-20 10:16:17 -04:00
|
|
|
url << "?page=#{page}" if page != 0
|
|
|
|
|
2014-08-13 16:12:44 -04:00
|
|
|
redirect_to url, status: 301
|
2013-02-10 13:50:26 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def track_visit_to_topic
|
2014-06-11 21:29:29 -04:00
|
|
|
topic_id = @topic_view.topic.id
|
|
|
|
ip = request.remote_ip
|
|
|
|
user_id = (current_user.id if current_user)
|
|
|
|
track_visit = should_track_visit_to_topic?
|
|
|
|
|
2014-08-03 21:06:06 -04:00
|
|
|
Scheduler::Defer.later "Track Link" do
|
|
|
|
IncomingLink.add(
|
|
|
|
referer: request.referer || flash[:referer],
|
|
|
|
host: request.host,
|
|
|
|
current_user: current_user,
|
|
|
|
topic_id: @topic_view.topic.id,
|
|
|
|
post_number: params[:post_number],
|
|
|
|
username: request['u'],
|
|
|
|
ip_address: request.remote_ip
|
|
|
|
)
|
2014-08-29 13:39:02 -04:00
|
|
|
end unless request.format.json?
|
2014-08-03 21:06:06 -04:00
|
|
|
|
2014-07-17 16:22:46 -04:00
|
|
|
Scheduler::Defer.later "Track Visit" do
|
2014-08-04 05:07:55 -04:00
|
|
|
TopicViewItem.add(topic_id, ip, user_id)
|
2016-05-14 04:06:29 -04:00
|
|
|
TopicUser.track_visit!(topic_id, user_id) if track_visit
|
2014-06-11 21:29:29 -04:00
|
|
|
end
|
2013-10-04 03:00:23 -04:00
|
|
|
|
2013-02-10 13:50:26 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def should_track_visit_to_topic?
|
2014-08-29 13:39:02 -04:00
|
|
|
!!((!request.format.json? || params[:track_visit]) && current_user)
|
2013-02-10 13:50:26 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def perform_show_response
|
2016-08-16 20:04:23 -04:00
|
|
|
|
|
|
|
if request.head?
|
|
|
|
head :ok
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2014-11-01 17:30:08 -04:00
|
|
|
topic_view_serializer = TopicViewSerializer.new(@topic_view, scope: guardian, root: false, include_raw: !!params[:include_raw])
|
2013-06-28 13:55:34 -04:00
|
|
|
|
2013-02-10 13:50:26 -05:00
|
|
|
respond_to do |format|
|
|
|
|
format.html do
|
2014-05-07 11:21:37 -04:00
|
|
|
@description_meta = @topic_view.topic.excerpt
|
2013-02-10 13:50:26 -05:00
|
|
|
store_preloaded("topic_#{@topic_view.topic.id}", MultiJson.dump(topic_view_serializer))
|
2015-08-12 17:00:16 -04:00
|
|
|
render :show
|
2013-02-10 13:50:26 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
format.json do
|
|
|
|
render_json_dump(topic_view_serializer)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2013-06-18 01:52:09 -04:00
|
|
|
|
|
|
|
def render_topic_changes(dest_topic)
|
|
|
|
if dest_topic.present?
|
|
|
|
render json: {success: true, url: dest_topic.relative_url}
|
|
|
|
else
|
|
|
|
render json: {success: false}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-09-04 11:53:00 -04:00
|
|
|
def move_posts_to_destination(topic)
|
2013-06-18 01:52:09 -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-10-29 15:30:06 -04:00
|
|
|
args[:category_id] = params[:category_id].to_i if params[:category_id].present?
|
2013-06-18 01:52:09 -04:00
|
|
|
|
2013-09-04 11:53:00 -04:00
|
|
|
topic.move_posts(current_user, post_ids_including_replies, args)
|
2013-06-18 01:52:09 -04:00
|
|
|
end
|
|
|
|
|
2013-10-28 02:12:07 -04:00
|
|
|
def check_for_status_presence(key, attr)
|
2015-03-13 20:18:05 -04:00
|
|
|
invalid_param(key) unless %w(pinned pinned_globally visible closed archived).include?(attr)
|
2013-10-28 02:12:07 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def invalid_param(key)
|
|
|
|
raise Discourse::InvalidParameters.new(key.to_sym)
|
|
|
|
end
|
|
|
|
|
|
|
|
def fetch_username
|
|
|
|
params.require(:user)
|
|
|
|
params[:user]
|
|
|
|
end
|
|
|
|
|
|
|
|
def fetch_email
|
|
|
|
params.require(:email)
|
|
|
|
params[:email]
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|