def set_allowed_and_addable_types(self): """ Folder restrictions and addable types """ def modify_types(types): old2new = {"Topic": "Collection"} types_tool = plone.api.portal.get_tool("portal_types") available_types = types_tool.objectIds() # replace old types with new types types = [old2new.get(t, t) for t in types] # filter out non existing types types = [t for t in types if t in available_types] return types data = json.loads(self.request.BODY) addable_types = data.get("addable_types", ()) addable_types = modify_types(addable_types) allowed_types = data.get("allowed_types", ()) allowed_types = modify_types(allowed_types) constrain_types_mode = data.get("constrain_types_mode", -1) if constrain_types_mode == -1: # AQUIRE return constrains = ISelectableConstrainTypes(self.context) if allowed_types: constrains.setLocallyAllowedTypes(allowed_types) if addable_types: constrains.setImmediatelyAddableTypes(addable_types) constrains.setConstrainTypesMode(constrain_types_mode) self.request.response.setStatus(204)
def migrate_annex(self): qi = self.context.portal_quickinstaller if not qi.isProductInstalled('imio.annex'): qi.installProduct('imio.annex') self.runProfileSteps('imio.project.pst', steps=['typeinfo'], run_dependencies=False) brains = self.catalog(object_provides=IProjectSpace.__identifier__) for brain in brains: pst_obj = brain.getObject() behaviour = ISelectableConstrainTypes(pst_obj) behaviour.setConstrainTypesMode(1) behaviour.setLocallyAllowedTypes(['strategicobjective', 'annex', ]) behaviour.setImmediatelyAddableTypes(['strategicobjective', 'annex', ]) portal = api.portal.get() configure_iconified_category(portal) annexTypeId = calculate_category_id(portal.categorization.annexes.get('annexes-pst')) brains = self.catalog(object_provides=IFile.__identifier__) for brain in brains: file_obj = brain.getObject() parent = file_obj.aq_parent if parent.portal_type in ['pstprojectspace', 'strategicobjective', 'operationalobjective', 'pstaction', 'pstsubaction', 'task']: annexId = file_obj.id api.content.delete(obj=parent[annexId]) api.content.create( container=parent, type='annex', id=annexId, title=file_obj.Title(), description=file_obj.Description(), content_category=annexTypeId, file=file_obj.file, ) transaction.commit()
def testMoreNotIncludedWhenNotNecessary(self): constraints = ISelectableConstrainTypes(self.folder) constraints.setConstrainTypesMode(1) constraints.setLocallyAllowedTypes(('Document',)) constraints.setImmediatelyAddableTypes(('Document',)) actions = self.menu.getMenuItems(self.folder, self.request) self.assertEqual(len(actions), 2) self.assertEqual(actions[0]['extra']['id'], 'document') self.assertEqual(actions[1]['extra']['id'], 'settings')
def testNonStructualFolderShowsParent(self): self.folder.invokeFactory('Folder', 'folder1') directlyProvides(self.folder.folder1, INonStructuralFolder) constraints = ISelectableConstrainTypes(self.folder.folder1) constraints.setConstrainTypesMode(1) constraints.setLocallyAllowedTypes(('Document',)) constraints.setImmediatelyAddableTypes(('Document',)) actions = self.menu.getMenuItems(self.folder.folder1, self.request) self.assertEqual(len(actions), 0)
def testNonStructualFolderShowsParent(self): self.folder.invokeFactory('Folder', 'folder1') directlyProvides(self.folder.folder1, INonStructuralFolder) constraints = ISelectableConstrainTypes(self.folder.folder1) constraints.setConstrainTypesMode(1) constraints.setLocallyAllowedTypes(('Document', )) constraints.setImmediatelyAddableTypes(('Document', )) actions = self.menu.getMenuItems(self.folder.folder1, self.request) self.assertEqual(len(actions), 0)
def testMoreNotIncludedWhenNotNecessary(self): constraints = ISelectableConstrainTypes(self.folder) constraints.setConstrainTypesMode(1) constraints.setLocallyAllowedTypes(('Document',)) constraints.setImmediatelyAddableTypes(('Document',)) actions = self.menu.getMenuItems(self.folder, self.request) self.assertEqual(len(actions), 2) self.assertEqual(actions[0]['extra']['id'], 'document') self.assertEqual(actions[1]['extra']['id'], 'plone-contentmenu-settings')
def testMoreIncluded(self): constraints = ISelectableConstrainTypes(self.folder) constraints.setConstrainTypesMode(1) constraints.setLocallyAllowedTypes(('Document', 'Image',)) constraints.setImmediatelyAddableTypes(('Document',)) actions = self.menu.getMenuItems(self.folder, self.request) self.failIf('image' in [a['extra']['id'] for a in actions]) self.failUnless('document' in [a['extra']['id'] for a in actions]) self.failUnless('more' in [a['extra']['id'] for a in actions]) self.failUnless('settings' in [a['extra']['id'] for a in actions])
def testMoreIncluded(self): constraints = ISelectableConstrainTypes(self.folder) constraints.setConstrainTypesMode(1) constraints.setLocallyAllowedTypes(('Document', 'Image',)) constraints.setImmediatelyAddableTypes(('Document',)) actions = self.menu.getMenuItems(self.folder, self.request) self.failIf('image' in [a['extra']['id'] for a in actions]) self.failUnless('document' in [a['extra']['id'] for a in actions]) self.failUnless('plone-contentmenu-more' in [a['extra']['id'] for a in actions]) self.failUnless('plone-contentmenu-settings' in [a['extra']['id'] for a in actions])
def testNonStructualFolderShowsParent(self): self.folder.invokeFactory('Folder', 'folder1') directlyProvides(self.folder.folder1, INonStructuralFolder) constraints = ISelectableConstrainTypes(self.folder.folder1) constraints.setConstrainTypesMode(1) constraints.setLocallyAllowedTypes(('Document', )) constraints.setImmediatelyAddableTypes(('Document', )) actions = self.menu.getMenuItems(self.folder.folder1, self.request) action_ids = [a['extra']['id'] for a in actions] self.assertTrue('event' in action_ids)
def testNonStructualFolderShowsParent(self): self.folder.invokeFactory('Folder', 'folder1') directlyProvides(self.folder.folder1, INonStructuralFolder) constraints = ISelectableConstrainTypes(self.folder.folder1) constraints.setConstrainTypesMode(1) constraints.setLocallyAllowedTypes(('Document',)) constraints.setImmediatelyAddableTypes(('Document',)) actions = self.menu.getMenuItems(self.folder.folder1, self.request) action_ids = [a['extra']['id'] for a in actions] self.assertTrue('event' in action_ids)
def testAddMenuWithNothingToAddButWithAvailableConstrainSettings(self): constraints = ISelectableConstrainTypes(self.folder) constraints.setConstrainTypesMode(1) constraints.setLocallyAllowedTypes(()) constraints.setImmediatelyAddableTypes(()) items = self.menu.getMenuItems(self.folder, self.request) factoriesMenuItem = [ i for i in items if i['extra']['id'] == 'plone-contentmenu-factories'][0] self.assertEqual(len(factoriesMenuItem['submenu']), 1) self.assertEqual(factoriesMenuItem['submenu'][0]['extra']['id'], 'plone-contentmenu-settings')
def testAddMenuWithNothingToAddButWithAvailableMorePage(self): constraints = ISelectableConstrainTypes(self.folder) constraints.setConstrainTypesMode(1) constraints.setLocallyAllowedTypes(('Document',)) constraints.setImmediatelyAddableTypes(()) self.folder.manage_permission('Modify constrain types', ('Manager',)) setRoles(self.portal, TEST_USER_ID, ['Contributor']) items = self.menu.getMenuItems(self.folder, self.request) factoriesMenuItem = [i for i in items if i['extra']['id'] == 'plone-contentmenu-factories'][0] self.assertEqual(len(factoriesMenuItem['submenu']), 1) self.assertEqual(factoriesMenuItem['submenu'][0]['extra']['id'], 'plone-contentmenu-more')
def handleSave(self, action): data, errors = self.extractData() if errors: return immediately_addable_types = [t for t in data['current_prefer'] if t not in data['current_allow']] locally_allowed_types = data['current_prefer'] aspect = ISelectableConstrainTypes(self.context) aspect.setConstrainTypesMode(data['constrain_types_mode']) aspect.setLocallyAllowedTypes(locally_allowed_types) aspect.setImmediatelyAddableTypes(immediately_addable_types)
def testMoreIncluded(self): constraints = ISelectableConstrainTypes(self.folder) constraints.setConstrainTypesMode(1) constraints.setLocallyAllowedTypes(('Document', 'Image',)) constraints.setImmediatelyAddableTypes(('Document',)) actions = self.menu.getMenuItems(self.folder, self.request) self.assertFalse('image' in [a['extra']['id'] for a in actions]) self.assertTrue('document' in [a['extra']['id'] for a in actions]) self.assertTrue( 'plone-contentmenu-more' in [a['extra']['id'] for a in actions] ) self.assertTrue( 'plone-contentmenu-settings' in [a['extra']['id'] for a in actions] )
def testAddMenuWithNothingToAddButWithAvailableMorePage(self): constraints = ISelectableConstrainTypes(self.folder) constraints.setConstrainTypesMode(1) constraints.setLocallyAllowedTypes(('Document', )) constraints.setImmediatelyAddableTypes(()) self.folder.manage_permission('Modify constrain types', ('Manager', )) setRoles(self.portal, TEST_USER_ID, ['Contributor']) items = self.menu.getMenuItems(self.folder, self.request) factoriesMenuItem = [ i for i in items if i['extra']['id'] == 'plone-contentmenu-factories' ][0] self.assertEqual(len(factoriesMenuItem['submenu']), 1) self.assertEqual(factoriesMenuItem['submenu'][0]['extra']['id'], 'plone-contentmenu-more')
def handleAddedEvaluable(obj, event): with api.env.adopt_roles(roles='Manager'): constraints = ISelectableConstrainTypes(obj) constraints.setConstrainTypesMode(constrains.DISABLED) document = api.content.create(type='Document', title='Carta', container=obj) api.group.grant_roles(groupname='evaluators', roles=['Editor'], obj=document) constraints.setLocallyAllowedTypes(['Pdf File']) constraints.setImmediatelyAddableTypes(['Pdf File']) constraints.setConstrainTypesMode(constrains.ENABLED) for member in api.user.get_users(groupname='evaluators'): api.user.grant_roles(username=member.id, roles=['Reader'], obj=obj) api.content.disable_roles_acquisition(obj=obj) api.group.grant_roles(groupname='Reviewers', roles=['Reader'], obj=obj)
def testAddMenuWithAddViewExpr(self): # we need a dummy to test this - should test that if the item does not # support constrain types and there is constraints = ISelectableConstrainTypes(self.folder) constraints.setConstrainTypesMode(1) constraints.setLocallyAllowedTypes(('Document',)) constraints.setImmediatelyAddableTypes(('Document',)) self.folder.manage_permission('Modify constrain types', ('Manager',)) self.portal.portal_types['Document']._setPropValue( 'add_view_expr', 'string:custom_expr') items = self.menu.getMenuItems(self.folder, self.request) factoriesMenuItem = [ i for i in items if i['extra']['id'] == 'plone-contentmenu-factories'][0] self.assertEqual(factoriesMenuItem['submenu'][0]['action'], 'custom_expr')
def __call__(self): if hasattr(self.context.aq_base, CAROUSEL_ID): carousel = getattr(self.context, CAROUSEL_ID) else: pt = getToolByName(self.context, 'portal_types') newid = pt.constructContent( type_name='Folder', container=self.context, id='carousel', title='Carousel Banners' ) carousel = getattr(self.context, newid) # exclude the (Archetypes or Dexterity) folder from navigation if hasattr(aq_base(carousel), 'setExcludeFromNav'): carousel.setExcludeFromNav(True) elif hasattr(aq_base(carousel), 'exclude_from_nav'): carousel.exclude_from_nav = True # mark the new folder as a Carousel folder alsoProvides(carousel, ICarouselFolder) # make sure Carousel banners are addable within the new folder addPermissionsForRole(carousel, 'Manager', ('Carousel: Add Carousel Banner',)) addPermissionsForRole(carousel, 'Site Administrator', ('Carousel: Add Carousel Banner',)) addPermissionsForRole(carousel, 'Owner', ('Carousel: Add Carousel Banner',)) addPermissionsForRole(carousel, 'Contributor', ('Carousel: Add Carousel Banner',)) addPermissionsForRole(carousel, 'Editor', ('Carousel: Add Carousel Banner',)) # make sure *only* Carousel banners are addable aspect = ISelectableConstrainTypes(carousel) aspect.setConstrainTypesMode(1) aspect.setLocallyAllowedTypes(['Carousel Banner']) aspect.setImmediatelyAddableTypes(['Carousel Banner']) carousel.reindexObject() self.request.RESPONSE.redirect( carousel.absolute_url() + '/@@edit-carousel' )
def handleSave(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return allowed_types = data['allowed_types'] immediately_addable = [ t for t in allowed_types if t not in data['secondary_types']] aspect = ISelectableConstrainTypes(self.context) aspect.setConstrainTypesMode(data['constrain_types_mode']) aspect.setLocallyAllowedTypes(allowed_types) aspect.setImmediatelyAddableTypes(immediately_addable) contextURL = self.context.absolute_url() self.request.response.redirect(contextURL)
def handle_auto_folder_creation(self, folder, type_): # we only auto publish built-in repositories, otherwise, leave it be try: if api.content.get_state(obj=folder) != 'published': api.content.transition(obj=folder, transition='publish') except WorkflowException: pass aspect = ISelectableConstrainTypes(folder, None) if (aspect and (aspect.getConstrainTypesMode() != 1 or [type_] != aspect.getImmediatelyAddableTypes())): aspect.setConstrainTypesMode(1) try: aspect.setImmediatelyAddableTypes([type_]) except: pass if not getattr(folder, 'exclude_from_nav', False): # if auto generated path, exclude from nav folder.exclude_from_nav = True folder.reindexObject()
def __call__(self): if hasattr(self.context.aq_base, CAROUSEL_ID): carousel = getattr(self.context, CAROUSEL_ID) else: pt = getToolByName(self.context, 'portal_types') newid = pt.constructContent(type_name='Folder', container=self.context, id='carousel', title='Carousel Banners') carousel = getattr(self.context, newid) # exclude the (Archetypes or Dexterity) folder from navigation if hasattr(aq_base(carousel), 'setExcludeFromNav'): carousel.setExcludeFromNav(True) elif hasattr(aq_base(carousel), 'exclude_from_nav'): carousel.exclude_from_nav = True # mark the new folder as a Carousel folder alsoProvides(carousel, ICarouselFolder) # make sure Carousel banners are addable within the new folder addPermissionsForRole(carousel, 'Manager', ('Carousel: Add Carousel Banner', )) addPermissionsForRole(carousel, 'Site Administrator', ('Carousel: Add Carousel Banner', )) # make sure *only* Carousel banners are addable aspect = ISelectableConstrainTypes(carousel) aspect.setConstrainTypesMode(1) aspect.setLocallyAllowedTypes(['Carousel Banner']) aspect.setImmediatelyAddableTypes(['Carousel Banner']) carousel.reindexObject() self.request.RESPONSE.redirect(carousel.absolute_url() + '/@@edit-carousel')
def migrate_typerestriction(self): constraints = ISelectableConstrainTypes(self.new) constraints.setConstrainTypesMode(ENABLED) constraints.setImmediatelyAddableTypes(self.new_allowed) constraints.setLocallyAllowedTypes(self.new_allowed)
def constrain_types(folder, ftis): aspect = ISelectableConstrainTypes(folder) aspect.setConstrainTypesMode(1) aspect.setLocallyAllowedTypes(ftis) aspect.setImmediatelyAddableTypes(ftis)