Commit 538dd366 authored by Julien Muchembled's avatar Julien Muchembled

CategoryTool._setCategoryMemberShip: bugfixes and cleanup

- duplicated default categories were dropped when the list of categories was
  passed without their base categories
- accept any iterable for 'category_list'
parent 257306cd
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
"""\ """\
ERP portal_categories tool. ERP portal_categories tool.
""" """
from collections import deque
from OFS.Folder import Folder from OFS.Folder import Folder
from Products.CMFCore.utils import UniqueObject from Products.CMFCore.utils import UniqueObject
from Products.ERP5Type.Globals import InitializeClass, DTMLFile from Products.ERP5Type.Globals import InitializeClass, DTMLFile
...@@ -633,84 +633,54 @@ class CategoryTool( UniqueObject, Folder, Base ): ...@@ -633,84 +633,54 @@ class CategoryTool( UniqueObject, Folder, Base ):
category_list = (category_list, ) category_list = (category_list, )
elif category_list is None: elif category_list is None:
category_list = () category_list = ()
elif isinstance(category_list, (list, tuple)):
pass
else:
__traceback_info__ = (base_category_list, category_list)
raise TypeError('Category must be of string, tuple of string '
'or list of string type.')
if isinstance(base_category_list, str): if isinstance(base_category_list, str):
base_category_list = (base_category_list, ) base_category_list = (base_category_list, )
# Build the ckecked_permission filter
if checked_permission is not None: if checked_permission is not None:
checkPermission = self.portal_membership.checkPermission checkPermission = self.portal_membership.checkPermission
def permissionFilter(obj):
if checkPermission(checked_permission, obj):
return 0
else:
return 1
new_category_list = [] new_category_list = deque()
default_dict = {} default_base_category_set = set()
spec_len = len(spec) default_category_set = set()
for path in self._getCategoryList(context): for path in self._getCategoryList(context):
my_base_id = self.getBaseCategoryId(path) my_base_id = self.getBaseCategoryId(path)
if my_base_id not in base_category_list: if my_base_id in base_category_list:
# Keep each membership which is not in the if spec or checked_permission is not None:
# specified list of base_category ids
new_category_list.append(path)
else:
keep_it = 0
if spec_len != 0 or (checked_permission is not None):
obj = self.unrestrictedTraverse(path, None) obj = self.unrestrictedTraverse(path, None)
if obj is not None: if obj is not None:
if spec_len != 0:
# If spec is (), then we should keep nothing # If spec is (), then we should keep nothing
# Everything will be replaced # Everything will be replaced
# If spec is not (), Only keep this if not in our spec # If spec is not (), Only keep this if not in our spec
my_type = obj.portal_type if (spec and obj.portal_type not in spec) or not (
keep_it = (my_type not in spec) checked_permission is None or
if (not keep_it) and (checked_permission is not None): checkPermission(checked_permission, obj)):
keep_it = permissionFilter(obj)
if keep_it:
new_category_list.append(path) new_category_list.append(path)
elif keep_default: continue
# We must remember the default value # We must remember the default value for each replaced category
# for each replaced category if keep_default and my_base_id not in default_base_category_set:
if not default_dict.has_key(my_base_id): default_base_category_set.add(my_base_id)
default_dict[my_base_id] = path default_category_set.add(path)
# We now create a list of default category values
default_new_category_list = []
for path in default_dict.values():
if base or len(base_category_list) > 1:
if path in category_list:
default_new_category_list.append(path)
else: else:
if path[len(base_category_list[0])+1:] in category_list: # Keep each membership which is not in the
default_new_category_list.append(path) # specified list of base_category ids
new_category_list.append(path)
# Before we append new category values (except default values) # Before we append new category values (except default values)
# We must make sure however that multiple links are possible # We must make sure however that multiple links are possible
default_path_found = {} base = '' if base or len(base_category_list) > 1 \
else base_category_list[0] + '/'
for path in category_list: for path in category_list:
if not path in ('', None): if path not in ('', None):
if base or len(base_category_list) > 1: if base:
# Only keep path which are member of base_category_list path = base + path
if self.getBaseCategoryId(path) in base_category_list: elif self.getBaseCategoryId(path) not in base_category_list:
if path not in default_new_category_list or default_path_found.has_key(path): continue
default_path_found[path] = 1 if path in default_category_set:
new_category_list.append(path) default_category_set.remove(path)
new_category_list.appendleft(path)
else: else:
new_path = '%s/%s' % (base_category_list[0], path) new_category_list.append(path)
if new_path not in default_new_category_list: self._setCategoryList(context, new_category_list)
new_category_list.append(new_path)
# LOG("CategoryTool, setCategoryMembership", 0 ,
# 'new_category_list: %s' % str(new_category_list))
# LOG("CategoryTool, setCategoryMembership", 0 ,
# 'default_new_category_list: %s' % str(default_new_category_list))
self._setCategoryList(context, tuple(default_new_category_list + new_category_list))
security.declareProtected( Permissions.AccessContentsInformation, 'setDefaultCategoryMembership' ) security.declareProtected( Permissions.AccessContentsInformation, 'setDefaultCategoryMembership' )
......
...@@ -1075,6 +1075,27 @@ class TestCMFCategory(ERP5TypeTestCase): ...@@ -1075,6 +1075,27 @@ class TestCMFCategory(ERP5TypeTestCase):
# Check indexation # Check indexation
self.tic() self.tic()
def test_setCategoryMemberShip(self):
person = self.getPersonModule().newContent(portal_type='Person')
category_tool = self.getCategoriesTool()
bc = category_tool.newContent()
bc.newContent('a')
bc.newContent('b')
base = (bc.id + '/').__add__
def get(*args, **kw):
return category_tool.getCategoryMembershipList(person, *args, **kw)
def _set(*args, **kw):
return category_tool._setCategoryMembership(person, *args, **kw)
_set(bc.id, list('aa'))
self.assertEqual(get(bc.id), list('aa'))
_set(bc.id, list('baa'))
self.assertEqual(get(bc.id), list('aba'))
_set(bc.id, map(base, 'bb'), 1)
self.assertEqual(get(bc.id), list('bb'))
_set(bc.id, map(base, 'abb'), 1)
self.assertEqual(get(bc.id), list('bab'))
_set(bc.id, ())
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestCMFCategory)) suite.addTest(unittest.makeSuite(TestCMFCategory))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment