mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-30 19:08:10 -05:00
4a20d09523
in case of an absolute dupe just return the memoized post This works around issues with wordpress being crazy
250 lines
6.9 KiB
Ruby
250 lines
6.9 KiB
Ruby
require_dependency 'post_creator'
|
|
require_dependency 'post_destroyer'
|
|
require_dependency 'distributed_memoizer'
|
|
|
|
class PostsController < ApplicationController
|
|
|
|
# Need to be logged in for all actions here
|
|
before_filter :ensure_logged_in, except: [:show, :replies, :by_number, :short_link, :versions]
|
|
|
|
skip_before_filter :store_incoming_links, only: [:short_link]
|
|
skip_before_filter :check_xhr, only: [:markdown,:short_link]
|
|
|
|
def markdown
|
|
post = Post.where(topic_id: params[:topic_id].to_i, post_number: (params[:post_number] || 1).to_i).first
|
|
if post && guardian.can_see?(post)
|
|
render text: post.raw, content_type: 'text/plain'
|
|
else
|
|
raise Discourse::NotFound
|
|
end
|
|
end
|
|
|
|
def short_link
|
|
post = Post.find(params[:post_id].to_i)
|
|
IncomingLink.add(request,current_user)
|
|
redirect_to post.url
|
|
end
|
|
|
|
def create
|
|
params = create_params
|
|
|
|
key = params_key(params)
|
|
|
|
result = DistributedMemoizer.memoize(key, 120) do
|
|
post_creator = PostCreator.new(current_user, params)
|
|
post = post_creator.create
|
|
if post_creator.errors.present?
|
|
|
|
# If the post was spam, flag all the user's posts as spam
|
|
current_user.flag_linked_posts_as_spam if post_creator.spam?
|
|
|
|
"e" << MultiJson.dump(errors: post_creator.errors.full_messages)
|
|
else
|
|
post_serializer = PostSerializer.new(post, scope: guardian, root: false)
|
|
post_serializer.topic_slug = post.topic.slug if post.topic.present?
|
|
post_serializer.draft_sequence = DraftSequence.current(current_user, post.topic.draft_key)
|
|
"s" << MultiJson.dump(post_serializer)
|
|
end
|
|
end
|
|
|
|
|
|
payload = result[1..-1]
|
|
if result[0] == "e"
|
|
# don't memoize errors
|
|
$redis.del(DistributedMemoizer.redis_key(key))
|
|
render json: payload, status: 422
|
|
else
|
|
render json: payload
|
|
end
|
|
end
|
|
|
|
def update
|
|
params.require(:post)
|
|
|
|
post = Post.where(id: params[:id]).first
|
|
post.image_sizes = params[:image_sizes] if params[:image_sizes].present?
|
|
guardian.ensure_can_edit!(post)
|
|
|
|
# to stay consistent with the create api,
|
|
# we should allow for title changes and category changes here
|
|
# we should also move all of this to a post updater.
|
|
if post.post_number == 1 && (params[:title] || params[:post][:category])
|
|
post.topic.title = params[:title] if params[:title]
|
|
Topic.transaction do
|
|
post.topic.change_category(params[:post][:category])
|
|
post.topic.save
|
|
end
|
|
|
|
if post.topic.errors.present?
|
|
render_json_error(post.topic)
|
|
return
|
|
end
|
|
end
|
|
|
|
revisor = PostRevisor.new(post)
|
|
if revisor.revise!(current_user, params[:post][:raw])
|
|
TopicLink.extract_from(post)
|
|
end
|
|
|
|
|
|
if post.errors.present?
|
|
render_json_error(post)
|
|
return
|
|
end
|
|
|
|
post_serializer = PostSerializer.new(post, scope: guardian, root: false)
|
|
post_serializer.draft_sequence = DraftSequence.current(current_user, post.topic.draft_key)
|
|
link_counts = TopicLink.counts_for(guardian,post.topic, [post])
|
|
post_serializer.single_post_link_counts = link_counts[post.id] if link_counts.present?
|
|
post_serializer.topic_slug = post.topic.slug if post.topic.present?
|
|
|
|
result = {post: post_serializer.as_json}
|
|
if revisor.category_changed.present?
|
|
result[:category] = BasicCategorySerializer.new(revisor.category_changed, scope: guardian, root: false).as_json
|
|
end
|
|
|
|
render_json_dump(result)
|
|
end
|
|
|
|
def by_number
|
|
@post = Post.where(topic_id: params[:topic_id], post_number: params[:post_number]).first
|
|
guardian.ensure_can_see!(@post)
|
|
@post.revert_to(params[:version].to_i) if params[:version].present?
|
|
render_post_json(@post)
|
|
end
|
|
|
|
def show
|
|
@post = find_post_from_params
|
|
@post.revert_to(params[:version].to_i) if params[:version].present?
|
|
render_post_json(@post)
|
|
end
|
|
|
|
def destroy
|
|
post = find_post_from_params
|
|
guardian.ensure_can_delete!(post)
|
|
|
|
destroyer = PostDestroyer.new(current_user, post)
|
|
destroyer.destroy
|
|
|
|
render nothing: true
|
|
end
|
|
|
|
def recover
|
|
post = find_post_from_params
|
|
guardian.ensure_can_recover_post!(post)
|
|
destroyer = PostDestroyer.new(current_user, post)
|
|
destroyer.recover
|
|
post.reload
|
|
|
|
render_post_json(post)
|
|
end
|
|
|
|
def destroy_many
|
|
|
|
params.require(:post_ids)
|
|
|
|
posts = Post.where(id: params[:post_ids])
|
|
raise Discourse::InvalidParameters.new(:post_ids) if posts.blank?
|
|
|
|
# Make sure we can delete the posts
|
|
posts.each {|p| guardian.ensure_can_delete!(p) }
|
|
|
|
Post.transaction do
|
|
topic_id = posts.first.topic_id
|
|
posts.each {|p| p.destroy }
|
|
Topic.reset_highest(topic_id)
|
|
end
|
|
|
|
render nothing: true
|
|
end
|
|
|
|
# Retrieves a list of versions and who made them for a post
|
|
def versions
|
|
post = find_post_from_params
|
|
render_serialized(post.all_versions, VersionSerializer)
|
|
end
|
|
|
|
# Direct replies to this post
|
|
def replies
|
|
post = find_post_from_params
|
|
render_serialized(post.replies, PostSerializer)
|
|
end
|
|
|
|
# Returns the "you're creating a post education"
|
|
def education_text
|
|
|
|
end
|
|
|
|
def bookmark
|
|
post = find_post_from_params
|
|
if current_user
|
|
if params[:bookmarked] == "true"
|
|
PostAction.act(current_user, post, PostActionType.types[:bookmark])
|
|
else
|
|
PostAction.remove_act(current_user, post, PostActionType.types[:bookmark])
|
|
end
|
|
end
|
|
render nothing: true
|
|
end
|
|
|
|
|
|
protected
|
|
|
|
def find_post_from_params
|
|
finder = Post.where(id: params[:id] || params[:post_id])
|
|
|
|
# Include deleted posts if the user is staff
|
|
finder = finder.with_deleted if current_user.try(:staff?)
|
|
|
|
post = finder.first
|
|
guardian.ensure_can_see!(post)
|
|
post
|
|
end
|
|
|
|
def render_post_json(post)
|
|
post_serializer = PostSerializer.new(post, scope: guardian, root: false)
|
|
post_serializer.add_raw = true
|
|
render_json_dump(post_serializer)
|
|
end
|
|
|
|
private
|
|
|
|
def params_key(params)
|
|
"post##" << Digest::SHA1.hexdigest(params
|
|
.to_a
|
|
.concat([["user", current_user.id]])
|
|
.sort{|x,y| x[0] <=> y[0]}.join do |x,y|
|
|
"#{x}:#{y}"
|
|
end)
|
|
end
|
|
|
|
def create_params
|
|
permitted = [
|
|
:raw,
|
|
:topic_id,
|
|
:title,
|
|
:archetype,
|
|
:category,
|
|
:target_usernames,
|
|
:reply_to_post_number,
|
|
:image_sizes,
|
|
:auto_close_days,
|
|
:auto_track
|
|
]
|
|
|
|
# param munging for WordPress
|
|
params[:auto_track] = !(params[:auto_track].to_s == "false") if params[:auto_track]
|
|
|
|
if api_key_valid?
|
|
# php seems to be sending this incorrectly, don't fight with it
|
|
params[:skip_validations] = params[:skip_validations].to_s == "true"
|
|
permitted << :skip_validations
|
|
end
|
|
|
|
params.require(:raw)
|
|
params.permit(*permitted).tap do |whitelisted|
|
|
# TODO this does not feel right, we should name what meta_data is allowed
|
|
whitelisted[:meta_data] = params[:meta_data]
|
|
end
|
|
end
|
|
end
|