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)
This commit is contained in:
Frédéric Péters 2014-06-05 09:26:12 +02:00
parent dc81f71fc4
commit f08cff24d0
2 changed files with 28 additions and 1 deletions

View File

@ -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):

View File

@ -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