diff --git a/doc/development/api/general.rst b/doc/development/api/general.rst index 3526f866f..7d5b30f11 100644 --- a/doc/development/api/general.rst +++ b/doc/development/api/general.rst @@ -51,7 +51,7 @@ Backend .. automodule:: pretix.base.signals - :members: logentry_display, requiredaction_display + :members: logentry_display, logentry_object_link, requiredaction_display Vouchers """""""" diff --git a/doc/development/api/plugins.rst b/doc/development/api/plugins.rst index 6f914468e..ee770828f 100644 --- a/doc/development/api/plugins.rst +++ b/doc/development/api/plugins.rst @@ -114,6 +114,19 @@ method to make your receivers available:: def ready(self): from . import signals # NOQA +You can optionally specify code that is executed when your plugin is activated for an event +in the ``installed`` method:: + + class PaypalApp(AppConfig): + … + + def installed(self, event): + pass # Your code here + + +Note that ``installed`` will *not* be called if the plugin in indirectly activated for an event +because the event is created with settings copied from another event. + Views ----- diff --git a/src/pretix/base/models/log.py b/src/pretix/base/models/log.py index 9501a370d..748585146 100644 --- a/src/pretix/base/models/log.py +++ b/src/pretix/base/models/log.py @@ -8,6 +8,8 @@ from django.utils.functional import cached_property from django.utils.html import escape from django.utils.translation import pgettext_lazy, ugettext_lazy as _ +from pretix.base.signals import logentry_object_link + class LogEntry(models.Model): """ @@ -146,6 +148,9 @@ class LogEntry(models.Model): elif a_text: return a_text else: + for receiver, response in logentry_object_link.send(self.event, logentry=self): + if response: + return response return '' @cached_property diff --git a/src/pretix/base/signals.py b/src/pretix/base/signals.py index 69e56c0cc..5cdb0c179 100644 --- a/src/pretix/base/signals.py +++ b/src/pretix/base/signals.py @@ -166,6 +166,34 @@ to the user. The receivers are expected to return plain text. As with all event-plugin signals, the ``sender`` keyword argument will contain the event. """ +logentry_object_link = EventPluginSignal( + providing_args=["logentry"] +) +""" +To display the relationship of an instance of the ``LogEntry`` model to another model +to a human user, ``pretix.base.signals.logentry_object_link`` will be sent out with a +``logentry`` argument. + +The first received response that is not ``None`` will be used to display the related object +to the user. The receivers are expected to return a HTML link. The internal implementation +builds the links like this:: + + a_text = _('Tax rule {val}') + a_map = { + 'href': reverse('control:event.settings.tax.edit', kwargs={ + 'event': sender.slug, + 'organizer': sender.organizer.slug, + 'rule': logentry.content_object.id + }), + 'val': escape(logentry.content_object.name), + } + a_map['val'] = '{val}'.format_map(a_map) + return a_text.format_map(a_map) + +Make sure that any user content in the HTML code you return is properly escaped! +As with all event-plugin signals, the ``sender`` keyword argument will contain the event. +""" + requiredaction_display = EventPluginSignal( providing_args=["action", "request"] ) diff --git a/src/pretix/control/views/event.py b/src/pretix/control/views/event.py index 9efbb2f2f..05303ef2c 100644 --- a/src/pretix/control/views/event.py +++ b/src/pretix/control/views/event.py @@ -205,6 +205,10 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat if getattr(plugins_available[module], 'restricted', False): if not request.user.is_superuser: continue + + if hasattr(plugins_available[module].app, 'installed'): + getattr(plugins_available[module].app, 'installed')(self.request.event) + self.request.event.log_action('pretix.event.plugins.enabled', user=self.request.user, data={'plugin': module}) if module not in plugins_active: