From f08cff24d082768b3fd81bb4245691f3996578d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Thu, 5 Jun 2014 09:26:12 +0200 Subject: [PATCH] Allow users to be in treating_groups/recipient_groups default value (#4898) This requires a custom source property to go against proper component isolation, the thing is we know it will be a PrincipalSource and it would only be prefilled with groups, while we may need to also have some users in that list if the default value has some. (otherwise to would be cleaned up as invalid values before presenting the form to the user, removing the users from the default value, only keeping the groups) --- src/collective/dms/basecontent/source.py | 6 ++++++ src/collective/dms/basecontent/widget.py | 23 ++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/collective/dms/basecontent/source.py b/src/collective/dms/basecontent/source.py index ad0df17..8de8b44 100644 --- a/src/collective/dms/basecontent/source.py +++ b/src/collective/dms/basecontent/source.py @@ -8,6 +8,8 @@ class PrincipalSource(PrincipalSource): BLACKLIST = ('AuthenticatedUsers', 'Administrators', 'Site Administrators', 'Reviewers') + extra_default_values = None + def search_principals(self, groups_first=False, **kw): if kw: results = self.acl_users.searchPrincipals(groups_first=True, **kw) @@ -15,6 +17,10 @@ class PrincipalSource(PrincipalSource): # if no kw, we have been called from source __iter__ because # of Chosen widget populate_select attribute is set to True results = self.acl_users.searchGroups() + if self.extra_default_values: + # cf widget.py, CustomAjaxChosenMultiSelectionWidget::source + results = list(results) + results.extend(self.acl_users.searchUsers(id=self.extra_default_values)) return [r for r in results if r.get('groupid', None) not in self.BLACKLIST] def searchGroups(self, **kwargs): diff --git a/src/collective/dms/basecontent/widget.py b/src/collective/dms/basecontent/widget.py index 1af492f..a226284 100644 --- a/src/collective/dms/basecontent/widget.py +++ b/src/collective/dms/basecontent/widget.py @@ -1,13 +1,34 @@ +import zope.component + +from zope.schema.interfaces import ISource, IContextSourceBinder from zope.interface import implementer import z3c.form.interfaces +from z3c.form import interfaces, util, value + from collective.z3cform.chosen.widget import AjaxChosenMultiSelectionWidget +class CustomAjaxChosenMultiSelectionWidget(AjaxChosenMultiSelectionWidget): + @property + def source(self): + # We have a custom source property because we know it will be a + # PrincipalSource and it would only be prefilled with groups, + # while we may need to also have some users in that list if the + # default value has some. (otherwise to would be cleaned up as invalid + # values before presenting the form to the user, removing the users + # from the default value, only keeping the groups) + source = self.field.bind(self.context).value_type.source + adapter = zope.component.queryMultiAdapter( + (self.context, self.request, self.form, self.field, self), + interfaces.IValue, name='default') + if adapter: + source.extra_default_values = adapter.get() + return source @implementer(z3c.form.interfaces.IFieldWidget) def AjaxChosenMultiFieldWidget(field, request): widget = z3c.form.widget.FieldWidget(field, - AjaxChosenMultiSelectionWidget(request)) + CustomAjaxChosenMultiSelectionWidget(request)) widget.populate_select = True widget.ignoreMissing = True return widget