2013-02-05 14:16:51 -05:00
|
|
|
require_dependency 'category_serializer'
|
|
|
|
|
|
|
|
class CategoriesController < ApplicationController
|
|
|
|
|
2018-03-02 21:53:29 -05:00
|
|
|
requires_login except: [:index, :categories_and_latest, :categories_and_top, :show, :redirect, :find_by_slug]
|
2018-01-31 23:17:59 -05:00
|
|
|
|
2017-08-31 00:06:56 -04:00
|
|
|
before_action :fetch_category, only: [:show, :update, :destroy]
|
|
|
|
before_action :initialize_staff_action_logger, only: [:create, :update, :destroy]
|
2018-03-02 21:53:29 -05:00
|
|
|
skip_before_action :check_xhr, only: [:index, :categories_and_latest, :categories_and_top, :redirect]
|
2014-10-16 12:15:31 -04:00
|
|
|
|
|
|
|
def redirect
|
2015-03-08 20:45:36 -04:00
|
|
|
redirect_to path("/c/#{params[:path]}")
|
2014-10-16 12:15:31 -04:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
def index
|
2016-08-17 17:23:16 -04:00
|
|
|
discourse_expires_in 1.minute
|
|
|
|
|
2013-09-11 15:33:05 -04:00
|
|
|
@description = SiteSetting.site_description
|
|
|
|
|
2017-03-08 11:31:30 -05:00
|
|
|
parent_category = Category.find_by(slug: params[:parent_category_id]) || Category.find_by(id: params[:parent_category_id].to_i)
|
|
|
|
|
2016-08-18 19:47:00 -04:00
|
|
|
category_options = {
|
|
|
|
is_homepage: current_homepage == "categories".freeze,
|
2016-08-22 17:01:43 -04:00
|
|
|
parent_category_id: params[:parent_category_id],
|
2017-03-08 11:31:30 -05:00
|
|
|
include_topics: include_topics(parent_category)
|
2016-08-18 19:47:00 -04:00
|
|
|
}
|
2013-10-17 02:44:56 -04:00
|
|
|
|
2016-08-17 17:23:16 -04:00
|
|
|
@category_list = CategoryList.new(guardian, category_options)
|
|
|
|
@category_list.draft_key = Draft::NEW_TOPIC
|
2018-03-02 21:53:29 -05:00
|
|
|
@category_list.draft_sequence = DraftSequence.current(
|
|
|
|
current_user,
|
|
|
|
Draft::NEW_TOPIC
|
|
|
|
)
|
2016-08-29 16:47:44 -04:00
|
|
|
@category_list.draft = Draft.get(current_user, Draft::NEW_TOPIC, @category_list.draft_sequence) if current_user
|
2013-05-28 21:15:30 -04:00
|
|
|
|
2017-06-12 13:50:30 -04:00
|
|
|
@title = "#{I18n.t('js.filters.categories.title')} - #{SiteSetting.title}" unless category_options[:is_homepage]
|
2015-06-08 12:07:35 -04:00
|
|
|
|
2013-04-26 13:10:41 -04:00
|
|
|
respond_to do |format|
|
2016-08-17 17:23:16 -04:00
|
|
|
format.html do
|
|
|
|
store_preloaded(@category_list.preload_key, MultiJson.dump(CategoryListSerializer.new(@category_list, scope: guardian)))
|
2016-08-22 17:01:43 -04:00
|
|
|
|
2018-03-02 21:53:29 -05:00
|
|
|
style = SiteSetting.desktop_category_page_style
|
|
|
|
topic_options = {
|
|
|
|
per_page: SiteSetting.categories_topics,
|
|
|
|
no_definitions: true
|
|
|
|
}
|
|
|
|
|
|
|
|
if style == "categories_and_latest_topics".freeze
|
|
|
|
@topic_list = TopicQuery.new(current_user, topic_options).list_latest
|
|
|
|
elsif style == "categories_and_top_topics".freeze
|
|
|
|
@topic_list = TopicQuery.new(nil, topic_options).list_top_for(SiteSetting.top_page_default_timeframe.to_sym)
|
|
|
|
end
|
|
|
|
|
|
|
|
if @topic_list.present?
|
|
|
|
store_preloaded(
|
|
|
|
@topic_list.preload_key,
|
|
|
|
MultiJson.dump(TopicListSerializer.new(@topic_list, scope: guardian))
|
|
|
|
)
|
2016-08-22 17:01:43 -04:00
|
|
|
end
|
|
|
|
|
2016-08-17 17:23:16 -04:00
|
|
|
render
|
|
|
|
end
|
|
|
|
|
|
|
|
format.json { render_serialized(@category_list, CategoryListSerializer) }
|
2013-04-26 13:10:41 -04:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
2013-02-07 10:45:24 -05:00
|
|
|
|
2016-08-29 16:47:44 -04:00
|
|
|
def categories_and_latest
|
2018-03-02 21:53:29 -05:00
|
|
|
categories_and_topics(:latest)
|
|
|
|
end
|
2016-08-29 16:47:44 -04:00
|
|
|
|
2018-03-02 21:53:29 -05:00
|
|
|
def categories_and_top
|
|
|
|
categories_and_topics(:top)
|
2016-08-29 16:47:44 -04:00
|
|
|
end
|
|
|
|
|
2013-10-21 00:24:37 -04:00
|
|
|
def move
|
2015-08-27 13:14:59 -04:00
|
|
|
guardian.ensure_can_create_category!
|
2013-10-21 00:33:42 -04:00
|
|
|
|
2013-10-21 00:24:37 -04:00
|
|
|
params.require("category_id")
|
|
|
|
params.require("position")
|
|
|
|
|
|
|
|
if category = Category.find(params["category_id"])
|
|
|
|
category.move_to(params["position"].to_i)
|
|
|
|
render json: success_json
|
|
|
|
else
|
|
|
|
render status: 500, json: failed_json
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-08-27 13:14:59 -04:00
|
|
|
def reorder
|
|
|
|
guardian.ensure_can_create_category!
|
|
|
|
|
|
|
|
params.require(:mapping)
|
|
|
|
change_requests = MultiJson.load(params[:mapping])
|
|
|
|
by_category = Hash[change_requests.map { |cat, pos| [Category.find(cat.to_i), pos] }]
|
|
|
|
|
|
|
|
unless guardian.is_admin?
|
|
|
|
raise Discourse::InvalidAccess unless by_category.keys.all? { |c| guardian.can_see_category? c }
|
|
|
|
end
|
|
|
|
|
|
|
|
by_category.each do |cat, pos|
|
|
|
|
cat.position = pos
|
2017-08-31 00:06:56 -04:00
|
|
|
cat.save! if cat.will_save_change_to_position?
|
2015-08-27 13:14:59 -04:00
|
|
|
end
|
2017-08-31 00:06:56 -04:00
|
|
|
|
2015-08-27 13:14:59 -04:00
|
|
|
render json: success_json
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def show
|
2014-03-05 17:21:55 -05:00
|
|
|
if Category.topic_create_allowed(guardian).where(id: @category.id).exists?
|
|
|
|
@category.permission = CategoryGroup.permission_types[:full]
|
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
render_serialized(@category, CategorySerializer)
|
|
|
|
end
|
|
|
|
|
|
|
|
def create
|
|
|
|
guardian.ensure_can_create!(Category)
|
|
|
|
|
2014-05-16 11:33:44 -04:00
|
|
|
position = category_params.delete(:position)
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
@category = Category.create(category_params.merge(user: current_user))
|
2013-02-07 10:45:24 -05:00
|
|
|
|
2015-09-17 03:51:32 -04:00
|
|
|
if @category.save
|
|
|
|
@category.move_to(position.to_i) if position
|
|
|
|
|
|
|
|
Scheduler::Defer.later "Log staff action create category" do
|
|
|
|
@staff_action_logger.log_category_creation(@category)
|
|
|
|
end
|
|
|
|
|
|
|
|
render_serialized(@category, CategorySerializer)
|
|
|
|
else
|
2016-09-21 23:30:19 -04:00
|
|
|
return render_json_error(@category) unless @category.save
|
2015-09-17 03:51:32 -04:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def update
|
|
|
|
guardian.ensure_can_edit!(@category)
|
2014-10-10 12:21:44 -04:00
|
|
|
|
|
|
|
json_result(@category, serializer: CategorySerializer) do |cat|
|
|
|
|
|
2014-05-16 11:33:44 -04:00
|
|
|
cat.move_to(category_params[:position].to_i) if category_params[:position]
|
2016-03-08 14:52:04 -05:00
|
|
|
category_params.delete(:position)
|
2014-10-10 12:21:44 -04:00
|
|
|
|
2016-03-08 14:52:04 -05:00
|
|
|
# properly null the value so the database constraint doesn't catch us
|
|
|
|
if category_params.has_key?(:email_in) && category_params[:email_in].blank?
|
2014-03-04 18:42:05 -05:00
|
|
|
category_params[:email_in] = nil
|
|
|
|
end
|
2014-10-10 12:21:44 -04:00
|
|
|
|
2016-03-08 14:52:04 -05:00
|
|
|
old_permissions = cat.permissions_params
|
2014-10-10 12:21:44 -04:00
|
|
|
|
2017-08-31 00:06:56 -04:00
|
|
|
if result = cat.update(category_params)
|
2018-03-27 02:23:35 -04:00
|
|
|
DiscourseEvent.trigger(:category_updated, cat)
|
2015-09-17 03:51:32 -04:00
|
|
|
Scheduler::Defer.later "Log staff action change category settings" do
|
|
|
|
@staff_action_logger.log_category_settings_change(@category, category_params, old_permissions)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
result
|
2014-10-10 12:21:44 -04:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2014-12-20 09:07:29 -05:00
|
|
|
def update_slug
|
|
|
|
@category = Category.find(params[:category_id].to_i)
|
|
|
|
guardian.ensure_can_edit!(@category)
|
|
|
|
|
|
|
|
custom_slug = params[:slug].to_s
|
|
|
|
|
|
|
|
if custom_slug.present? && @category.update_attributes(slug: custom_slug)
|
2018-03-27 02:23:35 -04:00
|
|
|
DiscourseEvent.trigger(:category_updated, @category)
|
2014-12-20 09:07:29 -05:00
|
|
|
render json: success_json
|
|
|
|
else
|
|
|
|
render_json_error(@category)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-04-17 05:17:39 -04:00
|
|
|
def set_notifications
|
|
|
|
category_id = params[:category_id].to_i
|
|
|
|
notification_level = params[:notification_level].to_i
|
|
|
|
|
2014-11-03 10:57:50 -05:00
|
|
|
CategoryUser.set_notification_level_for_category(current_user, notification_level, category_id)
|
2014-04-17 05:17:39 -04:00
|
|
|
render json: success_json
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def destroy
|
2013-04-18 17:07:06 -04:00
|
|
|
guardian.ensure_can_delete!(@category)
|
|
|
|
@category.destroy
|
2013-10-21 00:24:37 -04:00
|
|
|
|
2015-09-17 03:51:32 -04:00
|
|
|
Scheduler::Defer.later "Log staff action delete category" do
|
|
|
|
@staff_action_logger.log_category_deletion(@category)
|
|
|
|
end
|
|
|
|
|
2013-10-21 00:24:37 -04:00
|
|
|
render json: success_json
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2016-03-14 12:38:29 -04:00
|
|
|
def find_by_slug
|
|
|
|
params.require(:category_slug)
|
|
|
|
@category = Category.find_by_slug(params[:category_slug], params[:parent_category_slug])
|
|
|
|
guardian.ensure_can_see!(@category)
|
|
|
|
|
|
|
|
@category.permission = CategoryGroup.permission_types[:full] if Category.topic_create_allowed(guardian).where(id: @category.id).exists?
|
|
|
|
render_serialized(@category, CategorySerializer)
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
private
|
2018-03-02 21:53:29 -05:00
|
|
|
def categories_and_topics(topics_filter)
|
|
|
|
discourse_expires_in 1.minute
|
|
|
|
|
|
|
|
category_options = {
|
|
|
|
is_homepage: current_homepage == "categories".freeze,
|
|
|
|
parent_category_id: params[:parent_category_id],
|
|
|
|
include_topics: false
|
|
|
|
}
|
|
|
|
|
|
|
|
topic_options = {
|
|
|
|
per_page: SiteSetting.categories_topics,
|
|
|
|
no_definitions: true,
|
|
|
|
exclude_category_ids: Category.where(suppress_from_latest: true).pluck(:id)
|
|
|
|
}
|
|
|
|
|
|
|
|
result = CategoryAndTopicLists.new
|
|
|
|
result.category_list = CategoryList.new(guardian, category_options)
|
|
|
|
|
|
|
|
if topics_filter == :latest
|
|
|
|
result.topic_list = TopicQuery.new(current_user, topic_options).list_latest
|
|
|
|
elsif topics_filter == :top
|
|
|
|
result.topic_list = TopicQuery.new(nil, topic_options).list_top_for(SiteSetting.top_page_default_timeframe.to_sym)
|
|
|
|
end
|
|
|
|
|
|
|
|
draft_key = Draft::NEW_TOPIC
|
|
|
|
draft_sequence = DraftSequence.current(current_user, draft_key)
|
|
|
|
draft = Draft.get(current_user, draft_key, draft_sequence) if current_user
|
|
|
|
|
|
|
|
%w{category topic}.each do |type|
|
|
|
|
result.send(:"#{type}_list").draft = draft
|
|
|
|
result.send(:"#{type}_list").draft_key = draft_key
|
|
|
|
result.send(:"#{type}_list").draft_sequence = draft_sequence
|
|
|
|
end
|
|
|
|
|
|
|
|
render_serialized(result, CategoryAndTopicListsSerializer, root: false)
|
|
|
|
end
|
|
|
|
|
2013-03-26 18:06:21 -04:00
|
|
|
def required_param_keys
|
2013-03-14 09:16:57 -04:00
|
|
|
[:name, :color, :text_color]
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def category_params
|
2013-10-21 02:17:40 -04:00
|
|
|
@category_params ||= begin
|
|
|
|
required_param_keys.each do |key|
|
|
|
|
params.require(key)
|
|
|
|
end
|
2013-06-05 02:45:25 -04:00
|
|
|
|
2013-10-21 02:17:40 -04:00
|
|
|
if p = params[:permissions]
|
2017-07-27 21:20:09 -04:00
|
|
|
p.each do |k, v|
|
2013-10-21 02:17:40 -04:00
|
|
|
p[k] = v.to_i
|
|
|
|
end
|
2013-07-16 01:44:07 -04:00
|
|
|
end
|
|
|
|
|
2016-06-07 13:08:59 -04:00
|
|
|
if SiteSetting.tagging_enabled
|
|
|
|
params[:allowed_tags] ||= []
|
|
|
|
params[:allowed_tag_groups] ||= []
|
|
|
|
end
|
2016-05-31 16:46:40 -04:00
|
|
|
|
2014-07-09 22:01:46 -04:00
|
|
|
params.permit(*required_param_keys,
|
|
|
|
:position,
|
|
|
|
:email_in,
|
|
|
|
:email_in_allow_strangers,
|
2017-11-15 11:36:52 -05:00
|
|
|
:mailinglist_mirror,
|
2018-02-21 17:56:18 -05:00
|
|
|
:suppress_from_latest,
|
2016-12-18 08:38:55 -05:00
|
|
|
:all_topics_wiki,
|
2014-07-09 22:01:46 -04:00
|
|
|
:parent_category_id,
|
|
|
|
:auto_close_hours,
|
2014-10-10 12:21:44 -04:00
|
|
|
:auto_close_based_on_last_post,
|
2016-12-02 02:15:34 -05:00
|
|
|
:uploaded_logo_id,
|
|
|
|
:uploaded_background_id,
|
2014-12-03 19:23:59 -05:00
|
|
|
:slug,
|
2016-01-12 06:06:51 -05:00
|
|
|
:allow_badges,
|
2015-07-02 16:18:59 -04:00
|
|
|
:topic_template,
|
2016-11-01 12:18:31 -04:00
|
|
|
:sort_order,
|
|
|
|
:sort_ascending,
|
2016-12-15 17:46:43 -05:00
|
|
|
:topic_featured_link_allowed,
|
2017-02-21 18:08:09 -05:00
|
|
|
:show_subcategory_list,
|
2017-03-01 12:03:12 -05:00
|
|
|
:num_featured_topics,
|
2017-03-02 10:56:04 -05:00
|
|
|
:default_view,
|
2017-03-08 11:31:30 -05:00
|
|
|
:subcategory_list_style,
|
2017-03-22 16:54:12 -04:00
|
|
|
:default_top_period,
|
2018-03-28 14:40:26 -04:00
|
|
|
:minimum_required_tags,
|
2017-07-27 21:20:09 -04:00
|
|
|
custom_fields: [params[:custom_fields].try(:keys)],
|
|
|
|
permissions: [*p.try(:keys)],
|
|
|
|
allowed_tags: [],
|
|
|
|
allowed_tag_groups: [])
|
2013-10-21 02:17:40 -04:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
2013-04-18 17:07:06 -04:00
|
|
|
|
|
|
|
def fetch_category
|
2014-05-06 09:41:59 -04:00
|
|
|
@category = Category.find_by(slug: params[:id]) || Category.find_by(id: params[:id].to_i)
|
2013-04-18 17:07:06 -04:00
|
|
|
end
|
2015-09-17 03:51:32 -04:00
|
|
|
|
|
|
|
def initialize_staff_action_logger
|
|
|
|
@staff_action_logger = StaffActionLogger.new(current_user)
|
|
|
|
end
|
2016-08-29 16:47:44 -04:00
|
|
|
|
2017-07-27 21:20:09 -04:00
|
|
|
def include_topics(parent_category = nil)
|
2018-03-02 21:53:29 -05:00
|
|
|
style = SiteSetting.desktop_category_page_style
|
2016-08-29 16:47:44 -04:00
|
|
|
view_context.mobile_view? ||
|
2018-03-02 21:53:29 -05:00
|
|
|
params[:include_topics] ||
|
|
|
|
(parent_category && parent_category.subcategory_list_includes_topics?) ||
|
|
|
|
style == "categories_with_featured_topics".freeze ||
|
|
|
|
style == "categories_with_top_topics".freeze
|
2016-08-29 16:47:44 -04:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|