def getImmediatelyAddableTypes(self, context=None): """ If constraints are enabled, return the locally immediately addable tpes. If the setting is ACQUIRE, acquire the immediately addable types from the parent, according to the rules described in the interface. If constraints are disabled, use the default addable types """ if context is None: context = self.context mode = self.getConstrainTypesMode() default_addable = [ t.getId() for t in self.getDefaultAddableTypes(context) ] if mode == DISABLED: return default_addable elif mode == ENABLED: if hasattr(self.context, 'immediately_addable_types'): return self._filterByDefaults( self.context.immediately_addable_types, context) return default_addable elif mode == ACQUIRE: parent = self.context.__parent__ parent_constrain_adapter = ISelectableConstrainTypes(parent, None) if not parent_constrain_adapter: return default_addable return self._filterByDefaults( parent_constrain_adapter.getImmediatelyAddableTypes(context), context) else: raise Exception("Wrong constraint setting. %i is an invalid value", mode)
def allowedContentTypes(self, context=None): """ returns constrained allowed types as list of fti's. There is a try/except for handle AT folders inside DX containers """ if context is None: context = self mode = self.getConstrainTypesMode() # Short circuit if we are disabled or acquiring from non-compatible # parent parent = getParent(self) if mode == DISABLED or (mode == ACQUIRE and not parent): return PortalFolder.allowedContentTypes(self) elif mode == ACQUIRE and not parentPortalTypeEqual(self): globalTypes = self.getDefaultAddableTypes(context) if parent.portal_type == 'Plone Site': return globalTypes else: try: allowed = list(parent.getLocallyAllowedTypes(context)) except AttributeError: # parent is a DX content? behavior = ISelectableConstrainTypes(parent) if not behavior: # return context addable types return get_context_ftis(self) allowed = behavior.getLocallyAllowedTypes(context) return [fti for fti in globalTypes if fti.getId() in allowed] else: return get_context_ftis(self)
def getImmediatelyAddableTypes(self, context=None): """ If constraints are enabled, return the locally immediately addable tpes. If the setting is ACQUIRE, acquire the immediately addable types from the parent, according to the rules described in the interface. If constraints are disabled, use the default addable types """ if context is None: context = self.context mode = self.getConstrainTypesMode() default_addable = [t.getId() for t in self.getDefaultAddableTypes(context)] if mode == DISABLED: return default_addable elif mode == ENABLED: if hasattr(self.context, 'immediately_addable_types'): return self._filterByDefaults( self.context.immediately_addable_types, context) elif mode == ACQUIRE: parent = self.context.__parent__ parent_constrain_adapter = ISelectableConstrainTypes(parent, None) if not parent_constrain_adapter: return default_addable return self._filterByDefaults( parent_constrain_adapter.getImmediatelyAddableTypes(context), context) else: raise Exception( "Wrong constraint setting. %i is an invalid value", mode)
def allowedContentTypes(self, context=None): """ If constraints are enabled, return the locally allowed types. If the setting is ACQUIRE, acquire the locally allowed types according to the ACQUIRE rules, described in the interface. If constraints are disabled, use the default addable types This method returns the FTI, NOT the FTI id, like most other methods. """ if context is None: context = self.context mode = self.getConstrainTypesMode() default_addable = self.getDefaultAddableTypes(context) if mode == DISABLED: return default_addable elif mode == ENABLED: if hasattr(self.context, 'locally_allowed_types'): return [t for t in default_addable if t.getId() in self.context.locally_allowed_types] else: return default_addable elif mode == ACQUIRE: parent = self.context.__parent__ parent_constrain_adapter = ISelectableConstrainTypes(parent, None) if not parent_constrain_adapter: return default_addable return_tids = self._filterByDefaults( parent_constrain_adapter.getLocallyAllowedTypes(context), context) return [t for t in default_addable if t.getId() in return_tids] else: raise Exception( "Wrong constraint setting. %i is an invalid value", mode)
def configura_menu_apoio(portal): folder = portal["menu-de-apoio"] behavior = ISelectableConstrainTypes(folder) behavior.setConstrainTypesMode(constrains.ENABLED) # Permitimos apenas links behavior.setImmediatelyAddableTypes(["Link"]) folder.setLayout("folder_summary_view")
def test_immediatelyAllowedTypesInvalidValuesGetFiltered(self): behavior = ISelectableConstrainTypes(self.folder) behavior.setConstrainTypesMode(constrains.ENABLED) self.folder.immediately_addable_types = self.types_id_subset + \ ['invalid'] self.assertEqual(self.types_id_subset, behavior.getImmediatelyAddableTypes())
def test_immediatelyAllowedTypesInvalidValuesGetFiltered(self): behavior = ISelectableConstrainTypes(self.folder) behavior.setConstrainTypesMode(constrains.ENABLED) self.folder.immediately_addable_types = self.types_id_subset + \ ['invalid'] self.assertEqual( self.types_id_subset, behavior.getImmediatelyAddableTypes())
def allowedContentTypes(self, context=None): """ If constraints are enabled, return the locally allowed types. If the setting is ACQUIRE, acquire the locally allowed types according to the ACQUIRE rules, described in the interface. If constraints are disabled, use the default addable types This method returns the FTI, NOT the FTI id, like most other methods. """ if context is None: context = self.context mode = self.getConstrainTypesMode() default_addable = self.getDefaultAddableTypes(context) if mode == DISABLED: return default_addable elif mode == ENABLED: if hasattr(self.context, 'locally_allowed_types'): return [ t for t in default_addable if t.getId() in self.context.locally_allowed_types ] else: return default_addable elif mode == ACQUIRE: parent = self.context.__parent__ parent_constrain_adapter = ISelectableConstrainTypes(parent, None) if not parent_constrain_adapter: return default_addable return_tids = self._filterByDefaults( parent_constrain_adapter.getLocallyAllowedTypes(context), context) return [t for t in default_addable if t.getId() in return_tids] else: raise Exception("Wrong constraint setting. %i is an invalid value", mode)
def test_foo_folder_constraintypes(self): foo = self.portal.get('foo') if IS_PLONE_5 or IS_PLONE_APP_MULTILINGUAL_2: constrains = ISelectableConstrainTypes(foo) self.assertEqual(constrains.getConstrainTypesMode(), constraintypes.ENABLED, 'Constraint types are not enabled on folder foo') self.assertItemsEqual(constrains.getImmediatelyAddableTypes(), ['Folder'], 'Immediately addable types are not configured well') self.assertItemsEqual(constrains.getLocallyAllowedTypes(), ['Folder', 'Document'], 'Locally addable types are not configured well') else: self.assertEqual(foo.getConstrainTypesMode(), constraintypes.ENABLED, 'Constraint types are not enabled on folder foo') self.assertEqual(foo.getImmediatelyAddableTypes(), ('Folder',), 'Immediately addable types are not configured well') self.assertEqual(foo.getLocallyAllowedTypes(), ('Folder', 'Document'), 'Locally addable types are not configured well')
def test_setuphandler(self): self.assertIn('portal_history', self.layer['portal'].objectIds()) history = self.layer['portal'].portal_history self.assertEqual(history.getLayout(), 'collective_history_view') aspect = ISelectableConstrainTypes(history) addable = aspect.getImmediatelyAddableTypes() type_name = "collective.history.useraction" self.assertIn(type_name, addable)
def test_allowedContentTypesExit1(self): """ Constrains are disabled, use the portal ones """ behavior = ISelectableConstrainTypes(self.folder) types = behavior._getAddableTypesFor(self.portal, self.folder) behavior.setConstrainTypesMode(constrains.DISABLED) self.assertEqual(types, behavior.allowedContentTypes())
def test_allowedContentTypesExit2(self): """ Constrains are acquired, parent folder is Plone Site """ behavior = ISelectableConstrainTypes(self.folder) types = behavior._getAddableTypesFor(self.portal, self.folder) behavior.setConstrainTypesMode(constrains.ACQUIRE) self.assertEqual(types, behavior.allowedContentTypes())
def test_set_constrain_types(self): constraints = ISelectableConstrainTypes(self.belleville) self.assertListEqual(sorted(["Meeting", "Folder"]), sorted(constraints.getLocallyAllowedTypes())) utils.set_constrain_types(self.belleville, ["Meeting"]) self.assertListEqual(["Meeting"], constraints.getLocallyAllowedTypes()) utils.set_constrain_types(self.belleville, ["Meeting", "Folder"]) self.assertListEqual(["Folder", "Meeting"], constraints.getLocallyAllowedTypes())
def test_allowed_contenttypes(self): portal = self.layer['portal'] ff = ISelectableConstrainTypes(portal[defaults.FUNCTIONS_FOLDER_ID]) # not possible as test user self.assertEqual(len(ff.allowedContentTypes()), 0) # but if we become Manager setRoles(portal, TEST_USER_ID, ['Manager']) self.assertEqual(['Document', 'org.bccvl.content.function'], [fti.id for fti in ff.allowedContentTypes()]) # let's be Member again setRoles(portal, TEST_USER_ID, [])
def export_constraints(self, item, obj): constrains = ISelectableConstrainTypes(obj, None) if constrains is None: return item if constrains.getConstrainTypesMode() == ENABLED: key = "exportimport.constrains" item[key] = { "locally_allowed_types": constrains.getLocallyAllowedTypes(), "immediately_addable_types": constrains.getImmediatelyAddableTypes(), } return item
def get_addable_types(self): """Return menu item entries in a TAL-friendly form.""" data = { 'types': [], 'templates': [] } idnormalizer = queryUtility(IIDNormalizer) constraints = ISelectableConstrainTypes(self.folder, None) data['canConstrainTypes'] = False if constraints is not None: if constraints.canSetConstrainTypes() and \ constraints.getDefaultAddableTypes(): data.update({ 'canConstrainTypes': True, 'constrainUrl': '%s/folder_constraintypes_form' % ( self.folder.absolute_url(),) }) site_path = '/'.join(self.site.getPhysicalPath()) context = self.real_context if not IDexterityContainer.providedBy(context): context = aq_parent(context) folder_path = '/'.join(context.getPhysicalPath())[len(site_path):] if not folder_path: folder_path = '/' for t in self.folder.allowedContentTypes(): typeId = t.getId() data['types'].append({ 'id': typeId, 'safeId': idnormalizer.normalize(typeId), 'title': t.Title(), 'description': t.Description(), 'folderPath': folder_path }) try: site_templates = self.folder.template_list for t in site_templates: typeId = t.getId() data['templates'].append({ 'id': typeId, 'safeId': idnormalizer.normalize(typeId), 'title': t.Title(), 'description': t.Description(), 'folderPath': folder_path }) except AttributeError: pass return data
def createRule(self, context, rule_context, rule_id, rule_title, rule_description, rule_event, message, subject, for_types=None, area_id=None): """ Enabled types are taken from the Plone registry, or you can manually set them using for_types Id of the area (used for getting the notification group) is taken from current area, or by area_id param """ registry = queryUtility(IRegistry) settings = registry.forInterface(IGroupwareNotifySettings, check=False) #create the rule rule = Rule() rule.__name__ = rule_id rule.event = rule_event rule.title = rule_title rule.description = rule_description #add the rule to rule's storage storage = getUtility(IRuleStorage) # chooser = INameChooser(storage) if rule_id not in storage.keys(): storage[rule_id] = rule #set the action and add it to the rule action = MailForGroupwareNotificationAction(area_id) if settings and settings.default_email_sender: action.source = settings.default_email_sender action.sender = None action.subject = subject action.message = message rule.actions.append(action) if not for_types: #set the condition and add it to the rule if settings: behavior = ISelectableConstrainTypes(rule_context) allowed_types = behavior.getLocallyAllowedTypes() types_list = set(allowed_types).difference(settings.black_list) condition = PortalTypeCondition() condition.check_types=tuple(types_list) rule.conditions.append(condition) else: # explicit types condition=PortalTypeCondition() condition.check_types=tuple(for_types) rule.conditions.append(condition) logger.info('Created rule %s' % rule_id) #assignment rule_id=rule.id.replace('++rule++','') assignable = IRuleAssignmentManager(rule_context) assignable[rule_id] = RuleAssignment(rule_id) assignable[rule_id].bubbles=True get_assignments(storage[rule_id]).insert('/'.join(rule_context.getPhysicalPath())) logger.info('Enabled rule %s on %s' % (rule_id, rule_context.Title().decode('utf-8')))
def test_form_save_restrictions(self): self.browser.open(self.folder_url) self.browser.getLink('Restrictions').click() ctrl = lambda name: self.browser.getControl(name=name) self.browser.getControl("Type restrictions").value = ['1'] ctrl("form.widgets.allowed_types:list").value = ["Document", "Folder"] ctrl("form.widgets.secondary_types:list").value = ["Document"] self.browser.getControl("Save").click() aspect = ISelectableConstrainTypes(self.folder) self.assertEqual(1, aspect.getConstrainTypesMode()) self.assertEqual(["Document", "Folder"], aspect.getLocallyAllowedTypes()) self.assertEqual(["Folder"], aspect.getImmediatelyAddableTypes())
def allowedContentTypes(self, context=None): """ If constraints are enabled, return the locally allowed types. If the setting is ACQUIRE, acquire the locally allowed types according to the ACQUIRE rules, described in the interface. If constraints are disabled, use the default addable types This method returns the FTI, NOT the FTI id, like most other methods. """ portal = api.portal.getSite() subscribers = portal.portal_types.get('eea.meeting.subscribers') emails = portal.portal_types.get('eea.meeting.emails') if context is None: context = self.context mode = self.getConstrainTypesMode() default_addable = self.getDefaultAddableTypes(context) if mode == DISABLED: allowed = default_addable elif mode == ENABLED: if hasattr(self.context, 'locally_allowed_types'): allowed = [t for t in default_addable if t.getId() in self.context.locally_allowed_types] else: allowed = default_addable elif mode == ACQUIRE: parent = self.context.__parent__ parent_constrain_adapter = ISelectableConstrainTypes(parent, None) if not parent_constrain_adapter: allowed = default_addable else: return_tids = self._filterByDefaults( parent_constrain_adapter.getLocallyAllowedTypes(context)) allowed = [t for t in default_addable if t.getId() in return_tids] else: raise Exception( "Wrong constraint setting. %i is an invalid value", mode) if (IMeeting.providedBy(context) and context.get('subscribers')): if subscribers in allowed: allowed.remove(subscribers) if (IMeeting.providedBy(context) and context.get('emails')): if emails in allowed: allowed.remove(emails) return allowed
def test_locallyAllowedTypesDefaultWhenMultipleAcquired(self): """ Prevent regression. Multiple (two or more) acquisition from parent must not fail if user doesn't have add permission on parent. """ self.inner_folder.invokeFactory('folder', 'deeper_folder') deeper_folder = self.inner_folder.deeper_folder self.portal.acl_users._doAddUser('user_contributor', 'secret', ['Member'], []) deeper_folder.manage_addLocalRoles('user_contributor', ['Contributor']) login(self.portal, 'user_contributor') behavior = ISelectableConstrainTypes(deeper_folder) types = behavior.getLocallyAllowedTypes() self.assertTrue(len(types) > 0)
def post_install(context): """Post install script""" #if context.readDataFile('polklibraryslider_default.txt') is None: # return print "Running Post Install" # Add Group plone.app.portlets.ManagePortlets # plone.api.group.create(groupname='slider_image_editor', title='Slider Image Editor', description='Can edit and manage slider content') # Add Slider Folder site = api.portal.get() obj = api.content.create( type='Folder', title='Slider Images', description= 'This folder contains all the banner sliding images of your site. DO NOT DELETE, MOVE OR RENAME!', container=site) api.content.transition(obj, 'publish') obj.exclude_from_nav = True behavior = ISelectableConstrainTypes(obj) behavior.setConstrainTypesMode(constrains.ENABLED) behavior.setLocallyAllowedTypes(('linkable_image', )) behavior.setImmediatelyAddableTypes(('linkable_image', )) obj.reindexObject()
def test_allowedContentTypesExit3(self): """ Constrains are acquired, parent folder is of same type """ outer_behavior = ISelectableConstrainTypes(self.folder) assert len(outer_behavior.getLocallyAllowedTypes()) > 2 outer_behavior.setLocallyAllowedTypes(self.types_id_subset) outer_behavior.setConstrainTypesMode(constrains.ENABLED) behavior = ISelectableConstrainTypes(self.inner_folder) behavior.setConstrainTypesMode(constrains.ACQUIRE) self.assertEqual(self.types_id_subset, [x.getId() for x in behavior.allowedContentTypes()])
def createContentInFolder(folder_directori, folder_content): # Create content if folder_content[1] != "Folder": content_props = { 'title': folder_content[0], 'checkConstraints': False, 'exclude_from_nav': folder_content[2], 'allow_discussion': folder_content[3] } if folder_content[6] is not None: content_props['description'] = folder_content[6] if folder_content[7] is not None: content_props['text'] = IRichText['text'].fromUnicode( folder_content[7]) if folder_content[5] is not None: content_props['layout'] = folder_content[5] content = createContentInContainer(folder_directori, folder_content[1], **content_props) if folder_content[4] is not None: behavior = ISelectableConstrainTypes(content) behavior.setConstrainTypesMode(1) behavior.setLocallyAllowedTypes(folder_content[4]) behavior.setImmediatelyAddableTypes(folder_content[4]) else: createFolderAndContents(folder_directori, folder_content)
def render(self): try: from plone.protect.interfaces import IDisableCSRFProtection alsoProvides(self.request, IDisableCSRFProtection) except: pass portal = api.portal.get() pc = api.portal.get_tool(name='portal_catalog') communities = pc.searchResults(portal_type='ulearn.community') text = [] for community_brain in communities: # We assume that there will be only communities in Portal Site Root community = portal[community_brain.id] # Set on them the allowable content types behavior = ISelectableConstrainTypes(community['documents']) behavior.setConstrainTypesMode(1) behavior.setLocallyAllowedTypes( ('Document', 'File', 'Folder', 'Link', 'Image', 'privateFolder', 'ulearn.video', 'ulearn.video_embed')) behavior.setImmediatelyAddableTypes( ('Document', 'File', 'Folder', 'Link', 'Image', 'privateFolder', 'ulearn.video', 'ulearn.video_embed')) community.reindexObject() text.append('Migrated types community {}\n'.format( community.absolute_url())) return ''.join(text) + '\nDone!'
def test_template_not_addable(self): # Normal folder => image is allowed to add self._create_templates([{'id': 'i1', 'type': 'Image', 'title': 'Image1'}]) self._open_url("%s/create_from_template" % self.folder.absolute_url()) self.assertIn('>Image1</label>', self.browser.contents) # Image is not allowed anymore in this folder constrain = ISelectableConstrainTypes(self.folder) constrain.setConstrainTypesMode(constraintypes.ENABLED) constrain.setImmediatelyAddableTypes([self.folder_type]) transaction.commit() self._open_url("%s/create_from_template" % self.folder.absolute_url()) self.assertIn('No templates', self.browser.contents)
def createFolderAndContents(folder_directori, folder_data): # Create folder folder_props = { 'title': folder_data[0], 'checkConstraints': False, 'exclude_from_nav': folder_data[2], 'allow_discussion': folder_data[3] } if folder_data[5] is not None: folder_props['layout'] = folder_data[5] folder = createContentInContainer(folder_directori, folder_data[1], **folder_props) behavior = ISelectableConstrainTypes(folder) behavior.setConstrainTypesMode(1) behavior.setLocallyAllowedTypes(folder_data[4]) behavior.setImmediatelyAddableTypes(folder_data[4]) folder.reindexObject() # Create a contents for folder_content in folder_data[7]: createContentInFolder(folder, folder_content) if folder_data[6] is not None: folder.setDefaultPage(folder_data[6])
def __iter__(self): for item in self.previous: pathkey = self.pathkey(*item.keys())[0] constrainkey = self.constrainkey(*item.keys())[0] if not pathkey or not constrainkey or \ constrainkey not in item: # not enough info yield item continue obj = self.context.unrestrictedTraverse(item[pathkey].lstrip('/'), None) if obj is None: # path doesn't exist yield item continue constr = ISelectableConstrainTypes(obj, None) if constr is not None: constrain_dict = item[constrainkey] mode = constrain_dict['mode'] allowedtypes = constrain_dict['locallyallowedtypes'] addabletypes = constrain_dict['immediatelyaddabletypes'] if mode not in (constrains.ACQUIRE, constrains.DISABLED, constrains.ENABLED): # mode not valid [-1, 0, 1] yield item continue constr.setConstrainTypesMode(mode) if allowedtypes: constr.setLocallyAllowedTypes(allowedtypes) if addabletypes: constr.setImmediatelyAddableTypes(addabletypes) yield item
def set_constraintypes_config(self, obj, config): self.assertEquals({'mode', 'locally allowed', 'immediately addable'}, set(config)) ctypes = ISelectableConstrainTypes(obj) ctypes.setConstrainTypesMode(config['mode']) ctypes.setLocallyAllowedTypes(config['locally allowed']) ctypes.setImmediatelyAddableTypes(config['immediately addable'])
def test_form_bad_save(self): aspect = ISelectableConstrainTypes(self.folder) constraint_before = aspect.getConstrainTypesMode() assert constraint_before != 1, ("Default constraint should not be 1. " "Test is outdated.") self.browser.open(self.folder_url) self.browser.getLink('Restrictions').click() ctrl = lambda name: self.browser.getControl(name=name) self.browser.getControl("Type restrictions").value = ['1'] ctrl("form.widgets.allowed_types:list").value = ["Document"] ctrl("form.widgets.secondary_types:list").value = ["Document", "Folder"] self.browser.getControl("Save").click() self.assertEqual(constraint_before, aspect.getConstrainTypesMode()) self.assertTrue('Error' in self.browser.contents)
def test_form_save_restrictions(self): self.browser.open(self.folder_url) self.browser.getLink('Restrictions').click() def ctrl(name): return self.browser.getControl(name=name) self.browser.getControl('Type restrictions').value = ['1'] ctrl('form.widgets.allowed_types:list').value = ['Document', 'Folder'] ctrl('form.widgets.secondary_types:list').value = ['Document'] self.browser.getControl('Save').click() aspect = ISelectableConstrainTypes(self.folder) self.assertEqual(1, aspect.getConstrainTypesMode()) self.assertEqual(['Document', 'Folder'], aspect.getLocallyAllowedTypes()) self.assertEqual(['Folder'], aspect.getImmediatelyAddableTypes())
def templates(self): portal = getToolByName(self.context, 'portal_url').getPortalObject() catalog = getToolByName(self.context, 'portal_catalog') # Build the query. query = {"sort_on": "getObjPositionInParent"} constrain = ISelectableConstrainTypes(self.context, None) if constrain is not None: # search only for addable types query['portal_type'] = constrain.getImmediatelyAddableTypes() base_path = '/'.join(portal.getPhysicalPath()) brains = [] for templatefolder_location in self.templatefolder_locations(): query['path'] = { 'query': '%s/%s' % (base_path, templatefolder_location), 'depth': 1} brains.extend(catalog(**query)) return brains
def test_form_bad_save(self): aspect = ISelectableConstrainTypes(self.folder) constraint_before = aspect.getConstrainTypesMode() assert constraint_before != 1, ("Default constraint should not be 1. " "Test is outdated.") self.browser.open(self.folder_url) self.browser.getLink('Restrictions').click() ctrl = lambda name: self.browser.getControl(name=name) self.browser.getControl("Type restrictions").value = ['1'] ctrl("form.widgets.allowed_types:list").value = ["Document"] ctrl("form.widgets.secondary_types:list").value = [ "Document", "Folder" ] self.browser.getControl("Save").click() self.assertEqual(constraint_before, aspect.getConstrainTypesMode()) self.assertTrue('Error' in self.browser.contents)
def getImmediatelyAddableTypes(self, context=None): """Get the list of type ids which should be immediately addable. If enableTypeRestrictions is ENABLE, return the list set; if it is ACQUIRE, use the value from the parent; if it is DISABLE, return all type ids allowable on the item. There is a try/except for handle AT folders inside DX containers """ if context is None: context = self mode = self.getConstrainTypesMode() if mode == DISABLED: return [fti.getId() for fti in self.getDefaultAddableTypes(context)] elif mode == ENABLED: return self.getField('immediatelyAddableTypes').get(self) elif mode == ACQUIRE: parent = getParent(self) if not parent or parent.portal_type == 'Plone Site': return [fti.getId() for fti in PortalFolder.allowedContentTypes(self)] elif not parentPortalTypeEqual(self): default_allowed = [fti.getId() for fti in PortalFolder.allowedContentTypes(self)] try: immediately_addable = parent.getImmediatelyAddableTypes(context) except AttributeError: # parent is a DX content? behavior = ISelectableConstrainTypes(parent) if not behavior: # return context default addable types immediately_addable = self.getField('immediatelyAddableTypes').get(self) immediately_addable = behavior.getImmediatelyAddableTypes(context) return [t for t in immediately_addable if t in default_allowed] else: parent = aq_parent(aq_inner(self)) try: return parent.getImmediatelyAddableTypes(context) except AttributeError: # parent is a DX content? behavior = ISelectableConstrainTypes(parent) if not behavior: # return context default addable types return self.getField('immediatelyAddableTypes').get(self) return behavior.getImmediatelyAddableTypes(context) else: raise ValueError, "Invalid value for enableAddRestriction"
def onEventsFolderCreate(context, event, sample=True): # restrict what this folder can contain behavior = ISelectableConstrainTypes(context) behavior.setConstrainTypesMode(constrains.ENABLED) behavior.setImmediatelyAddableTypes(['Event']) behavior.setLocallyAllowedTypes(['Event', 'Collection']) # Create sample event and set publishing date to 01-01-YYYY if sample: # Calculate dates now = DateTime() start_date = DateTime() + 30 end_date = start_date + 1.0 / 24 item = createContentInContainer(context, "Event", id="sample", title="Sample Event", description="This is a sample Event", checkConstraints=False) item.text = RichTextValue(raw='<p>You may delete this item</p>', mimeType=u'text/html', outputMimeType='text/x-html-safe') item.setEffectiveDate(now) acc = IEventAccessor(item) acc.start = localize(start_date) acc.end = localize(end_date) # create 'upcoming' collection if 'upcoming' not in context.objectIds(): item = createContentInContainer( context, "Collection", id="upcoming", title='Upcoming Events', ) item.setQuery([{ u'i': u'path', u'o': u'plone.app.querystring.operation.string.absolutePath', u'v': u'%s::1' % context.UID() }, { u'i': u'portal_type', u'o': u'plone.app.querystring.operation.selection.any', u'v': [u'Event'] }]) item.setSort_on('start') # Set default page to the latest news collection context.setDefaultPage('upcoming')
def _getMenuItemsForContext(self, context, request): """Return menu item entries for the context only.""" results = [] if context is not None: allowed = [] constraints = [] haveMore = False include = None allowed = context.allowedContentTypes() constraints = IConstrainTypes(context, None) if constraints is not None: include = constraints.getImmediatelyAddableTypes() if len(include) < len(allowed): haveMore = True results = self._addable_types(context, request, allowed, include) if haveMore: url = '%s/folder_factories' % (context.absolute_url(),) results.append({ 'title' : _(u'folder_add_more', default=u'More\u2026'), 'description' : _(u'Show all available content types'), 'action' : url, 'selected' : False, 'icon' : None, 'extra' : {'id': 'more', 'separator': None, 'class': ''}, 'submenu' : None, }) selectableConstraints = ISelectableConstrainTypes(context, None) if selectableConstraints is not None: if selectableConstraints.canSetConstrainTypes() and \ selectableConstraints.getDefaultAddableTypes(): url = '%s/folder_constraintypes_form' % (context.absolute_url(),) results.append({'title' : _(u'folder_add_settings', default=u'Restrictions\u2026'), 'description' : _(u'title_configure_addable_content_types', default=u'Configure which content types can be added here'), 'action' : url, 'selected' : False, 'icon' : None, 'extra' : {'id': 'settings', 'separator': None, 'class': ''}, 'submenu' : None, }) return results
def various_update(self): # replace front-page frontpage = getattr(self.portal, 'front-page') frontpage.title = _translate("front_page_title") frontpage.description = _translate("front_page_descr") frontpage.text = richtextval(_translate("front_page_text")) transitions(frontpage, ('retract', 'publish_internally')) frontpage.reindexObject() self.portal.templates.layout = 'dg-templates-listing' # plonegroup-organization pgo = get_own_organization() behaviour = ISelectableConstrainTypes(pgo) behaviour.setConstrainTypesMode(1) behaviour.setLocallyAllowedTypes([]) behaviour.setImmediatelyAddableTypes([]) ISelectableConstrainTypes(pgo['echevins']).setConstrainTypesMode(0) ISelectableConstrainTypes(pgo['services']).setConstrainTypesMode(0)
def get_dashboard(self): write = False with api.env.adopt_roles(['Manager']): if 'dashboards' not in self.context.objectIds(): write = True api.content.create(type='Folder', title='Dashboards', id='dashboards', container=self.context, exclude_from_nav=True) dashboards = self.context['dashboards'] if not IHideFromBreadcrumbs.providedBy(dashboards): alsoProvides(dashboards, IHideFromBreadcrumbs) if api.content.get_state( obj=dashboards, default='Unknown') not in ('published', 'publish_internally'): write = True publish_content(dashboards) member = api.user.get_current() user_id = member.getId() if user_id not in dashboards.objectIds(): with api.env.adopt_roles(['Manager']): write = True # first make sure it is in allowed types... pts = api.portal.get_tool('portal_types') Folder = pts['Folder'] if 'Dashboard' not in Folder.allowed_content_types: allowed = list(Folder.allowed_content_types) allowed.append('Dashboard') Folder.allowed_content_types = tuple(allowed) aspect = ISelectableConstrainTypes(dashboards) if (aspect.getConstrainTypesMode() != 1 or ['Dashboard'] != aspect.getImmediatelyAddableTypes()): aspect.setConstrainTypesMode(1) aspect.setImmediatelyAddableTypes(['Dashboard']) api.content.create(type='Dashboard', title='Dashboard', id=user_id, container=dashboards, exclude_from_nav=True) dashboard = dashboards[user_id] if dashboard.getOwner().getId() != user_id: with api.env.adopt_roles(['Manager']): write = True dashboard.changeOwnership(member.getUser(), recursive=False) dashboard.reindexObjectSecurity() if write: alsoProvides(self.request, IDisableCSRFProtection) return dashboard
def render(self): try: from plone.protect.interfaces import IDisableCSRFProtection alsoProvides(self.request, IDisableCSRFProtection) except: pass portal = api.portal.get() pc = api.portal.get_tool(name='portal_catalog') communities = pc.searchResults(portal_type='ulearn.community') text = [] for community_brain in communities: # We assume that there will be only communities in Portal Site Root community = portal[community_brain.id] # Set on them the allowable content types behavior = ISelectableConstrainTypes(community['documents']) behavior.setConstrainTypesMode(1) behavior.setLocallyAllowedTypes(('Document', 'File', 'Folder', 'Link', 'Image', 'privateFolder', 'ulearn.video', 'ulearn.video_embed')) behavior.setImmediatelyAddableTypes(('Document', 'File', 'Folder', 'Link', 'Image', 'privateFolder', 'ulearn.video', 'ulearn.video_embed')) community.reindexObject() text.append('Migrated types community {}\n'.format(community.absolute_url())) return ''.join(text) + '\nDone!'
def render(self): pc = api.portal.get_tool(name='portal_catalog') communities = pc.searchResults(portal_type='ulearn.community') for community in communities: community = community.getObject() if 'discussion' not in community.objectIds(): # Create the default discussion container and set title discussion = createContentInContainer(community, 'Folder', title='discussion', checkConstraints=False) discussion.setTitle(community.translate(_(u'Discussion'))) discussion.setLayout('discussion_folder_view') alsoProvides(discussion, IDiscussionFolder) behavior = ISelectableConstrainTypes(discussion) behavior.setConstrainTypesMode(1) behavior.setLocallyAllowedTypes(('ulearn.discussion', 'Folder')) behavior.setImmediatelyAddableTypes(('ulearn.discussion', 'Folder')) # Blacklist the right column portlets on discussion right_manager = queryUtility(IPortletManager, name=u'plone.rightcolumn') blacklist = getMultiAdapter((discussion, right_manager), ILocalPortletAssignmentManager) blacklist.setBlacklistStatus(CONTEXT_CATEGORY, True) discussion.reindexObject() logger.info('Created discussion folder in {}'.format(community.absolute_url())) return 'Done.'
def test_form_save_restrictions(self): self.browser.open(self.folder_url) self.browser.getLink('Restrictions').click() def ctrl(name): return self.browser.getControl(name=name) self.browser.getControl('Type restrictions').value = ['1'] ctrl('form.widgets.allowed_types:list').value = ['Document', 'Folder'] ctrl('form.widgets.secondary_types:list').value = ['Document'] self.browser.getControl('Save').click() aspect = ISelectableConstrainTypes(self.folder) self.assertEqual(1, aspect.getConstrainTypesMode()) self.assertEqual( ['Document', 'Folder'], aspect.getLocallyAllowedTypes() ) self.assertEqual(['Folder'], aspect.getImmediatelyAddableTypes())
def test_constrainTypesAcquireDoesNotMatchParent(self): """ The inner folder should return constrains.ACQUIRE and not the actual value of its parent """ behavior1 = ISelectableConstrainTypes(self.folder) behavior2 = ISelectableConstrainTypes(self.inner_folder) behavior1.setConstrainTypesMode(constrains.DISABLED) self.assertEqual(constrains.ACQUIRE, behavior2.getConstrainTypesMode()) behavior1.setConstrainTypesMode(constrains.ENABLED) self.assertEqual(constrains.ACQUIRE, behavior2.getConstrainTypesMode())
def set_constraintypes_config(self, obj, config): self.assertEquals( {'mode', 'locally allowed', 'immediately addable'}, set(config)) ctypes = ISelectableConstrainTypes(obj) ctypes.setConstrainTypesMode(config['mode']) ctypes.setLocallyAllowedTypes(config['locally allowed']) ctypes.setImmediatelyAddableTypes(config['immediately addable'])
def import_constrains(self, obj, item): if not item.get("exportimport.constrains"): return constrains = ISelectableConstrainTypes(obj, None) if constrains is None: return constrains.setConstrainTypesMode(ENABLED) locally_allowed_types = item["exportimport.constrains"][ "locally_allowed_types"] constrains.setLocallyAllowedTypes(locally_allowed_types) immediately_addable_types = item["exportimport.constrains"][ "immediately_addable_types"] constrains.setImmediatelyAddableTypes(immediately_addable_types)
def _updateFolder(obj, types=None, view=None, authenticated_roles=None): if view is not None: obj.setLayout(view) if types is not None: aspect = ISelectableConstrainTypes(obj) addable = aspect.getLocallyAllowedTypes() if types != addable: aspect.setConstrainTypesMode(1) # Need to be globally allowed in order to be set as locally allowed # or to create a custom folderish content type with # "allowed_content_types" # Only a blacklist, not a whitelist setattr(obj, 'locally_allowed_types', types) setattr(obj, 'immediately_addable_types', types) if authenticated_roles is not None: obj.manage_setLocalRoles('AuthenticatedUsers', authenticated_roles) # Move view permission from Anonymous to Member obj.manage_permission(View, acquire=False, roles=('Authenticated', 'Member', 'Manager', 'Site Administrator'))
def test_form_bad_save(self): aspect = ISelectableConstrainTypes(self.folder) constraint_before = aspect.getConstrainTypesMode() assert constraint_before != 1, ('Default constraint should not be 1. ' 'Test is outdated.') self.browser.open(self.folder_url) self.browser.getLink('Restrictions').click() def ctrl(name): return self.browser.getControl(name=name) self.browser.getControl('Type restrictions').value = ['1'] ctrl('form.widgets.allowed_types:list').value = ['Document'] ctrl('form.widgets.secondary_types:list').value = [ 'Document', 'Folder' ] self.browser.getControl('Save').click() self.assertEqual(constraint_before, aspect.getConstrainTypesMode()) self.assertTrue('Error' in self.browser.contents)
def guards(self): immediately_addable = True context_state = getMultiAdapter((self.context.aq_inner, self.request), name='plone_context_state') container = context_state.folder() try: constraint = ISelectableConstrainTypes(container) immediately_addable = 'File' in constraint.getImmediatelyAddableTypes( ) except TypeError: pass return [ api.user.has_permission('Add portal content', obj=self.context), api.user.has_permission('plone.app.contenttypes: Add File', obj=self.context), immediately_addable, [ i for i in _allowedTypes(self.request, self.context) if i.id in ('Image', 'File') ] ]
def configura_servicos(portal): folder = portal.servicos behavior = ISelectableConstrainTypes(folder) behavior.setConstrainTypesMode(constrains.ENABLED) # Permitimos apenas links behavior.setImmediatelyAddableTypes(['Link']) folder.setLayout('summary_view')
def configura_imagens(portal): folder = portal.imagens behavior = ISelectableConstrainTypes(folder) behavior.setConstrainTypesMode(constrains.ENABLED) # Permitimos apenas imagens behavior.setImmediatelyAddableTypes(['Image']) folder.setLayout('summary_view')
def configura_menu_relevancia(portal): folder = portal['menu-de-relevancia'] behavior = ISelectableConstrainTypes(folder) behavior.setConstrainTypesMode(constrains.ENABLED) # Permitimos apenas links behavior.setImmediatelyAddableTypes(['Link']) folder.setLayout('summary_view')
def test_allowedContentTypesExit4(self): """ Constrains are enabled """ behavior = ISelectableConstrainTypes(self.folder) behavior.setLocallyAllowedTypes(self.types_id_subset) behavior.setConstrainTypesMode(constrains.ENABLED) self.assertEqual(self.types_id_subset, [x.getId() for x in behavior.allowedContentTypes()])
def _showConstrainOptions(self): addContext = self._addContext() constrain = ISelectableConstrainTypes(addContext, None) if constrain is None: return False elif constrain.canSetConstrainTypes() and constrain.getDefaultAddableTypes(): return True elif len(constrain.getLocallyAllowedTypes()) < len(constrain.getImmediatelyAddableTypes()): return True