2019-05-02 18:17:27 -04:00
# frozen_string_literal: true
2013-02-05 14:16:51 -05:00
# A class we can use to serialize the site data
class Site
include ActiveModel :: Serialization
2019-03-16 07:48:57 -04:00
cattr_accessor :preloaded_category_custom_fields
2022-07-13 20:54:31 -04:00
def self . reset_preloaded_category_custom_fields
self . preloaded_category_custom_fields = Set . new
end
reset_preloaded_category_custom_fields
2019-03-16 07:48:57 -04:00
2022-01-27 22:02:02 -05:00
##
# Sometimes plugins need to have additional data or options available
# when rendering custom markdown features/rules that are not available
# on the default opts.discourse object. These additional options should
# be namespaced to the plugin adding them.
#
# ```
# Site.markdown_additional_options["chat"] = { limited_pretty_text_markdown_rules: [] }
# ```
#
# These are passed down to markdown rules on opts.discourse.additionalOptions.
cattr_accessor :markdown_additional_options
self . markdown_additional_options = { }
2021-07-19 01:54:19 -04:00
def self . add_categories_callbacks ( & block )
categories_callbacks << block
end
def self . categories_callbacks
@categories_callbacks || = [ ]
end
2013-05-13 04:04:03 -04:00
def initialize ( guardian )
@guardian = guardian
end
2013-02-05 14:16:51 -05:00
def site_setting
SiteSetting
end
def notification_types
2013-03-01 07:07:44 -05:00
Notification . types
2013-02-05 14:16:51 -05:00
end
def trust_levels
2021-06-01 16:11:48 -04:00
TrustLevel . levels
2013-02-05 14:16:51 -05:00
end
2013-02-07 10:45:24 -05:00
2014-09-26 14:48:34 -04:00
def user_fields
2021-10-28 14:28:31 -04:00
UserField . includes ( :user_field_options ) . order ( :position ) . all
2014-09-26 14:48:34 -04:00
end
2021-07-22 03:18:18 -04:00
def self . categories_cache_key
" site_categories_ #{ Discourse . git_version } "
end
2021-06-23 03:21:11 -04:00
def self . clear_cache
2021-07-22 03:18:18 -04:00
Discourse . cache . delete ( categories_cache_key )
2021-06-23 03:21:11 -04:00
end
def self . all_categories_cache
# Categories do not change often so there is no need for us to run the
# same query and spend time creating ActiveRecord objects for every requests.
#
# Do note that any new association added to the eager loading needs a
# corresponding ActiveRecord callback to clear the categories cache.
2021-07-22 03:18:18 -04:00
Discourse . cache . fetch ( categories_cache_key , expires_in : 30 . minutes ) do
2013-07-16 01:44:07 -04:00
categories = Category
2022-10-07 11:00:44 -04:00
. includes ( :uploaded_logo , :uploaded_logo_dark , :uploaded_background , :tags , :tag_groups , category_required_tag_groups : :tag_group )
2015-09-28 02:49:39 -04:00
. joins ( 'LEFT JOIN topics t on t.id = categories.topic_id' )
2015-09-28 02:43:38 -04:00
. select ( 'categories.*, t.slug topic_slug' )
2013-11-06 16:56:49 -05:00
. order ( :position )
2021-06-23 03:21:11 -04:00
. to_a
if preloaded_category_custom_fields . present?
Category . preload_custom_fields (
categories ,
preloaded_category_custom_fields
)
end
2015-02-20 01:30:31 -05:00
2021-06-23 03:21:11 -04:00
ActiveModel :: ArraySerializer . new (
categories ,
each_serializer : SiteCategorySerializer
) . as_json
end
end
def categories
@categories || = begin
categories = [ ]
self . class . all_categories_cache . each do | category |
if @guardian . can_see_serialized_category? ( category_id : category [ :id ] , read_restricted : category [ :read_restricted ] )
2021-06-27 22:39:13 -04:00
categories << category
2021-06-23 03:21:11 -04:00
end
end
2013-07-16 01:44:07 -04:00
2015-09-22 23:13:34 -04:00
with_children = Set . new
categories . each do | c |
2021-06-27 22:39:13 -04:00
if c [ :parent_category_id ]
with_children << c [ :parent_category_id ]
2015-09-22 23:13:34 -04:00
end
end
2017-05-12 11:09:28 -04:00
allowed_topic_create = nil
unless @guardian . is_admin?
allowed_topic_create_ids =
@guardian . anonymous? ? [ ] : Category . topic_create_allowed ( @guardian ) . pluck ( :id )
allowed_topic_create = Set . new ( allowed_topic_create_ids )
end
2013-07-16 01:44:07 -04:00
2014-02-24 14:52:21 -05:00
by_id = { }
2014-04-17 05:17:39 -04:00
2021-05-13 19:45:14 -04:00
notification_levels = CategoryUser . notification_levels_for ( @guardian . user )
2019-11-07 21:58:11 -05:00
default_notification_level = CategoryUser . default_notification_level
2015-12-20 01:47:02 -05:00
2014-06-17 21:21:53 -04:00
categories . each do | category |
2021-06-27 22:39:13 -04:00
category [ :notification_level ] = notification_levels [ category [ :id ] ] || default_notification_level
category [ :permission ] = CategoryGroup . permission_types [ :full ] if allowed_topic_create & . include? ( category [ :id ] ) || @guardian . is_admin?
category [ :has_children ] = with_children . include? ( category [ :id ] )
category [ :can_edit ] = @guardian . can_edit_serialized_category? (
category_id : category [ :id ] ,
read_restricted : category [ :read_restricted ]
)
by_id [ category [ :id ] ] = category
2013-07-16 01:44:07 -04:00
end
2014-02-24 14:52:21 -05:00
2021-06-27 22:39:13 -04:00
categories . reject! { | c | c [ :parent_category_id ] && ! by_id [ c [ :parent_category_id ] ] }
2021-07-19 01:54:19 -04:00
self . class . categories_callbacks . each do | callback |
callback . call ( categories )
end
2013-07-16 01:44:07 -04:00
categories
end
2013-02-07 10:45:24 -05:00
end
2013-02-05 14:16:51 -05:00
2019-02-14 09:35:58 -05:00
def groups
2021-09-16 22:34:04 -04:00
Group
. visible_groups ( @guardian . user , " name ASC " , include_everyone : true )
. includes ( :flair_upload )
2019-02-14 09:35:58 -05:00
end
2013-02-05 14:16:51 -05:00
def archetypes
2013-02-28 13:54:12 -05:00
Archetype . list . reject { | t | t . id == Archetype . private_message }
2013-02-05 14:16:51 -05:00
end
2018-07-31 11:18:50 -04:00
def auth_providers
Discourse . enabled_auth_providers
end
2014-02-24 14:24:18 -05:00
def self . json_for ( guardian )
2013-10-14 18:50:30 -04:00
if guardian . anonymous? && SiteSetting . login_required
2014-01-20 08:41:11 -05:00
return {
periods : TopTopic . periods . map ( & :to_s ) ,
filters : Discourse . filters . map ( & :to_s ) ,
2021-10-28 14:28:31 -04:00
user_fields : UserField . includes ( :user_field_options ) . order ( :position ) . all . map do | userfield |
2015-08-17 15:44:08 -04:00
UserFieldSerializer . new ( userfield , root : false , scope : guardian )
2018-08-07 04:20:09 -04:00
end ,
auth_providers : Discourse . enabled_auth_providers . map do | provider |
AuthProviderSerializer . new ( provider , root : false , scope : guardian )
2017-09-07 09:15:29 -04:00
end
2014-01-20 08:41:11 -05:00
} . to_json
2013-10-14 18:50:30 -04:00
end
2015-09-28 02:44:03 -04:00
seq = nil
if guardian . anonymous?
seq = MessageBus . last_id ( '/site_json' )
2019-12-03 04:05:53 -05:00
cached_json , cached_seq , cached_version = Discourse . redis . mget ( 'site_json' , 'site_json_seq' , 'site_json_version' )
2015-09-28 02:44:03 -04:00
if cached_json && seq == cached_seq . to_i && Discourse . git_version == cached_version
return cached_json
end
end
2013-05-13 04:04:03 -04:00
site = Site . new ( guardian )
2015-09-28 02:44:03 -04:00
json = MultiJson . dump ( SiteSerializer . new ( site , root : false , scope : guardian ) )
if guardian . anonymous?
2022-05-09 18:19:02 -04:00
Discourse . redis . multi do | transaction |
transaction . setex 'site_json' , 1800 , json
transaction . set 'site_json_seq' , seq
transaction . set 'site_json_version' , Discourse . git_version
2015-09-28 02:44:03 -04:00
end
end
json
end
2018-12-17 04:27:44 -05:00
SITE_JSON_CHANNEL = '/site_json'
2015-09-28 02:44:03 -04:00
def self . clear_anon_cache!
# publishing forces the sequence up
# the cache is validated based on the sequence
2018-12-17 04:27:44 -05:00
MessageBus . publish ( SITE_JSON_CHANNEL , '' )
2013-02-05 14:16:51 -05:00
end
2022-09-01 00:14:21 -04:00
def self . welcome_topic_banner_cache_key ( user_id )
" show_welcome_topic_banner: #{ user_id } "
end
2022-08-09 12:22:39 -04:00
def self . show_welcome_topic_banner? ( guardian )
2022-09-01 00:14:21 -04:00
return false if ! guardian . is_admin?
user_id = guardian . user . id
show_welcome_topic_banner = Discourse . cache . read ( welcome_topic_banner_cache_key ( user_id ) )
return show_welcome_topic_banner unless show_welcome_topic_banner . nil?
show_welcome_topic_banner = if ( user_id == User . first_login_admin_id )
Post . find_by ( " topic_id = :topic_id AND post_number = 1 AND version = 1 AND created_at > :created_at " , topic_id : SiteSetting . welcome_topic_id , created_at : 1 . month . ago ) . present?
else
false
end
2022-08-09 12:22:39 -04:00
2022-09-01 00:14:21 -04:00
Discourse . cache . write ( welcome_topic_banner_cache_key ( user_id ) , show_welcome_topic_banner )
show_welcome_topic_banner
2022-08-09 12:22:39 -04:00
end
2013-02-05 14:16:51 -05:00
end