Allow disabling hybrid plugin for all events at once only via form

This commit is contained in:
Mira Weller
2026-09-25 18:39:56 +02:00
parent e518b3f06c
commit bb5ba65a28
3 changed files with 46 additions and 41 deletions
+12 -1
View File
@@ -1394,16 +1394,27 @@ class SalesChannelForm(I18nModelForm):
class OrganizerPluginEventsForm(forms.Form):
active_on_organizer = forms.BooleanField(
label=_("Active on organizer-level"),
help_text=_("Enables or disables the organizer-wide features of this plugin."),
required=False,
)
events = SafeEventMultipleChoiceField(
queryset=Event.objects.none(),
widget=forms.CheckboxSelectMultiple(attrs={
'class': 'scrolling-multiple-choice scrolling-multiple-choice-large',
'data-checkbox-dependency': '#id_active_on_organizer'
}),
label=_("Events with active plugin"),
required=False,
)
def __init__(self, *args, **kwargs):
def __init__(self, *args, hybrid, **kwargs):
events = kwargs.pop('events')
super().__init__(*args, **kwargs)
if not hybrid:
del self.fields['active_on_organizer']
self.fields['events'].widget = forms.CheckboxSelectMultiple(attrs={
'class': 'scrolling-multiple-choice scrolling-multiple-choice-large',
})
self.fields['events'].queryset = events
@@ -43,7 +43,7 @@
<legend>{{ catlabel }}</legend>
<div class="plugin-list">
{% for plugin, is_active, settings_links, navigation_links, events_counter in plist %}
<div class="plugin-container {% if plugin.featured %}featured-plugin{% endif %}" id="plugin_{{ plugin.module }}" data-plugin-module="{{ plugin.module }}" data-plugin-name="{{ plugin.name }}">
<div class="plugin-container {% if plugin.featured %}featured-plugin{% endif %}" id="plugin_{{ plugin.module }}" data-plugin-module="{{ plugin.module }}" data-plugin-name="{{ plugin.name }}" data-plugin-level="{{ plugin.level }}">
{% if plugin.featured %}
<div class="panel panel-default">
<div class="panel-body">
@@ -89,8 +89,8 @@
Active ({{ count }} events)
{% endblocktrans %}
</span>
{% elif level == "event_organizer" %}
<span class="label label-info" data-is-active>
{% elif plugin.level == "event_organizer" %}
<span class="label label-success" data-is-active>
<span class="fa fa-check" aria-hidden="true"></span>
{% blocktrans trimmed count count=0 %}
Active ({{ count }} event)
@@ -143,13 +143,14 @@
</ul>
</div>
{% endif %}
<button class="btn btn-default{% if plugin.featured %} btn-lg{% endif %}" name="plugin:{{ plugin.module }}"
value="disable">{% trans "Disable" %}</button>
{% if plugin.level == "event_organizer" %}
<a class="btn btn-default {% if plugin.featured %} btn-lg{% endif %}"
href="{% url "control:organizer.settings.plugin-events" organizer=request.organizer.slug plugin=plugin.module %}">
{% trans "Manage events" %}
{% trans "Manage plugin and events ..." %}
</a>
{% else %}
<button class="btn btn-default{% if plugin.featured %} btn-lg{% endif %}" name="plugin:{{ plugin.module }}"
value="disable">{% trans "Disable" %}</button>
{% endif %}
</div>
{% else %}
+27 -34
View File
@@ -715,27 +715,9 @@ class OrganizerPlugins(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixi
elif value == "disable" and module in plugins_available:
pluginmeta = plugins_available[module]
level = getattr(pluginmeta, 'level', PLUGIN_LEVEL_EVENT)
if level not in (PLUGIN_LEVEL_ORGANIZER, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID):
if level != PLUGIN_LEVEL_ORGANIZER:
continue
if level == PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID:
events_to_disable = set(self.request.organizer.events.filter(
plugins__regex='(^|,)' + module + '(,|$)'
).values_list("pk", flat=True))
logentries_to_save = []
events_to_save = []
for e in self.request.organizer.events.filter(pk__in=events_to_disable):
logentries_to_save.append(
e.log_action('pretix.event.plugins.disabled', user=self.request.user,
data={'plugin': module}, save=False)
)
e.disable_plugin(module)
events_to_save.append(e)
Event.objects.bulk_update(events_to_save, fields=["plugins"])
LogEntry.objects.bulk_create(logentries_to_save)
self.object.log_action('pretix.organizer.plugins.disabled', user=self.request.user,
data={'plugin': module})
self.object.disable_plugin(module)
@@ -767,7 +749,9 @@ class OrganizerPluginEvents(OrganizerDetailViewMixin, OrganizerPermissionRequire
# Assumption: Who has access to modify organizer settings may see all events and disable/enable plugins
# for them. Otherwise, inconsistent situations occur.
kwargs["events"] = self.request.organizer.events.all()
kwargs["hybrid"] = self.plugin_level == PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID
kwargs["initial"] = {
"active_on_organizer": self.plugin.module in self.request.organizer.get_plugins(),
"events": self.request.organizer.events.filter(plugins__regex='(^|,)' + self.plugin.module + '(,|$)')
}
return kwargs
@@ -779,19 +763,12 @@ class OrganizerPluginEvents(OrganizerDetailViewMixin, OrganizerPermissionRequire
)
def dispatch(self, request, *args, **kwargs):
self.plugin = self.request.organizer.get_available_plugins().get(kwargs["plugin"])
self.plugin = self.request.organizer.get_available_plugins(filter_restricted=True).get(kwargs["plugin"])
self.plugin_level = getattr(self.plugin, "level", PLUGIN_LEVEL_EVENT)
if not self.plugin:
raise Http404(_("Unknown plugin."))
level = getattr(self.plugin, "level", PLUGIN_LEVEL_EVENT)
if level == PLUGIN_LEVEL_ORGANIZER:
if self.plugin_level == PLUGIN_LEVEL_ORGANIZER:
raise Http404(_("This plugin can only be enabled for the entire organizer account."))
if level == PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID and self.plugin.module not in self.request.organizer.get_plugins():
raise Http404(_("This plugin is currently not active on the organizer account."))
if getattr(self.plugin, 'restricted', False):
if self.plugin.module not in request.organizer.settings.allowed_restricted_plugins:
raise Http404(_("This plugin is currently not allowed for this organizer account."))
return super().dispatch(request, *args, **kwargs)
def get_success_url(self) -> str:
@@ -801,27 +778,43 @@ class OrganizerPluginEvents(OrganizerDetailViewMixin, OrganizerPermissionRequire
@transaction.atomic()
def form_valid(self, form):
organizer = self.request.organizer
enabled_events_before = set(
self.request.organizer.events.filter(plugins__regex='(^|,)' + self.plugin.module + '(,|$)').values_list("pk", flat=True)
organizer.events.filter(plugins__regex='(^|,)' + self.plugin.module + '(,|$)').values_list("pk", flat=True)
)
enabled_events_now = {e.pk for e in form.cleaned_data["events"]}
if self.plugin_level == PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID:
if not form.cleaned_data["active_on_organizer"]:
enabled_events_now = set()
if self.plugin.module in organizer.get_plugins():
organizer.log_action('pretix.organizer.plugins.disabled', user=self.request.user,
data={'plugin': self.plugin.module})
organizer.disable_plugin(self.plugin.module)
organizer.save()
else:
if self.plugin.module not in organizer.get_plugins():
organizer.log_action('pretix.organizer.plugins.enabled', user=self.request.user,
data={'plugin': self.plugin.module})
organizer.enable_plugin(self.plugin.module)
organizer.save()
events_to_enable = enabled_events_now - enabled_events_before
events_to_disable = enabled_events_before - enabled_events_now
events_to_save = []
logentries_to_save = []
for e in self.request.organizer.events.filter(pk__in=events_to_enable):
if not plugin_is_available(self.plugin, organizer=self.request.organizer, event=e):
for e in organizer.events.filter(pk__in=events_to_enable):
if not plugin_is_available(self.plugin, organizer=organizer, event=e):
messages.warning(self.request, _("This plugin cannot be activated for event {}.").format(e.name))
continue
logentries_to_save.append(
e.log_action('pretix.event.plugins.enabled', user=self.request.user, data={'plugin': self.plugin.module}, save=False)
)
e.enable_plugin(self.plugin.module, allow_restricted=self.request.organizer.settings.allowed_restricted_plugins)
e.enable_plugin(self.plugin.module, allow_restricted=organizer.settings.allowed_restricted_plugins)
events_to_save.append(e)
for e in self.request.organizer.events.filter(pk__in=events_to_disable):
for e in organizer.events.filter(pk__in=events_to_disable):
logentries_to_save.append(
e.log_action('pretix.event.plugins.disabled', user=self.request.user, data={'plugin': self.plugin.module}, save=False)
)