FIX: Don’t list values from disabled plugins

Currently, when a plugin registers a new reviewable type or extends a
list method (through `register_reviewble_type` and `extend_list_method`
respectively), the new array is statically computed and always returns
the same value. It will continue to return the same value even if the
plugin is disabled (it can be a problem in a multisite env too).

To address this issue, this patch changes how `extend_list_method`
works. It’s now using `DiscoursePluginRegistry.define_filtered_register`
to create a register on the fly and store the extra values from various
plugins. It then combines the original values with the ones from the
registry. The registry is already aware of disabled plugins, so when a
plugin is disabled, its registered values won’t be returned.
This commit is contained in:
Loïc Guitaut
2024-07-09 17:56:22 +02:00
committed by Loïc Guitaut
parent 66878a9e80
commit 5ec227334a
4 changed files with 71 additions and 23 deletions

View File

@ -4,6 +4,8 @@
# A class that handles interaction between a plugin and the Discourse App.
#
class DiscoursePluginRegistry
@@register_names = Set.new
# Plugins often need to be able to register additional handlers, data, or
# classes that will be used by core classes. This should be used if you
# need to control which type the registry is, and if it doesn't need to
@ -15,7 +17,7 @@ class DiscoursePluginRegistry
# - Defines instance method as a shortcut to the singleton method
# - Automatically deletes the register on registry.reset!
def self.define_register(register_name, type)
@@register_names ||= Set.new
return if respond_to?(register_name)
@@register_names << register_name
define_singleton_method(register_name) do
@ -36,13 +38,13 @@ class DiscoursePluginRegistry
# - Defines instance method as a shortcut to the singleton method
# - Automatically deletes the register on registry.reset!
def self.define_filtered_register(register_name)
return if respond_to?(register_name)
define_register(register_name, Array)
singleton_class.alias_method :"_raw_#{register_name}", :"#{register_name}"
define_singleton_method(register_name) do
unfiltered = public_send(:"_raw_#{register_name}")
unfiltered.filter { |v| v[:plugin].enabled? }.map { |v| v[:value] }.uniq
public_send(:"_raw_#{register_name}").filter_map { |h| h[:value] if h[:plugin].enabled? }.uniq
end
define_singleton_method("register_#{register_name.to_s.singularize}") do |value, plugin|