def _translations(self, missing): # Figure out the "closest" translation in the parent chain of the # context. We stop at both an INavigationRoot or an ISiteRoot to look # for translations. We do want to find something that is definitely # in the language the user asked for. context = aq_inner(self.context) translations = {} chain = aq_chain(context) first_pass = True _checkPermission = getSecurityManager().checkPermission for item in chain: if ISiteRoot.providedBy(item): # We have a site root, which works as a fallback has_view_permission = bool(_checkPermission('View', item)) for c in missing: translations[c] = (item, first_pass, has_view_permission) break elif IFactoryTempFolder.providedBy(item) or \ IFactoryTool.providedBy(item): # TempFolder or portal_factory, can't have a translation continue canonical = ITranslationManager(item, None) item_trans = canonical.get_translations() for code, trans in item_trans.items(): code = str(code) if code not in translations: # make a link to a translation only if the user # has view permission has_view_permission = bool(_checkPermission('View', trans)) if (not INavigationRoot.providedBy(item) and not has_view_permission): continue # If we don't yet have a translation for this language # add it and mark it as found translations[code] = (trans, first_pass, has_view_permission) missing = missing - set((code, )) if len(missing) <= 0: # We have translations for all break if INavigationRoot.providedBy(item): # Don't break out of the navigation root jail has_view_permission = bool(_checkPermission('View', item)) for c in missing: translations[c] = (item, False, has_view_permission) break first_pass = False # return a dict of language code to tuple. the first tuple element is # the translated object, the second argument indicates wether the # translation is a direct translation of the context or something from # higher up the translation chain return translations
def __call__(self, context, membersonly=False): workspace = find_workspace(context) catalog = getToolByName(context, 'portal_catalog') gtool = getToolByName(context, 'portal_groups') # users = getUtility( # IVocabularyFactory, # name='plone.principalsource.Users', # context=context)(context) if not workspace: workspace = context # Create a list of user depending on local roles and inherited # roles. Also read out users from groups users = set([]) groups = set([]) # Walk upwards until reach portal root or role acquire check fails portal = workspace.portal_url.getPortalObject() cont = True while cont: if context == portal: break if IFactoryTool.providedBy(context): # this is portal_factory - skip it context = aq_parent(aq_inner(context)) continue if IFactoryTool.providedBy(aq_parent(context)): # this is the 'Ticket Box' temp folder # within portal_factory - skip it context = aq_parent(aq_inner(context)) continue userroles = portal.acl_users._getLocalRolesForDisplay(context) # Use dict's to auto. prevent duplicated entries for user, roles, role_type, name in userroles: if role_type == u'user' and name not in users: users.add(name) elif role_type == u'group' and user not in groups: groups.add(name) if getattr(aq_base(context), '__ac_local_roles_block__', None): cont = False else: context = aq_parent(context) # Go throught groups an add their containing users to the user list for groupid in groups: group = gtool.getGroupById(groupid) if group: members = set(group.getGroupMemberIds()) else: continue # Put together users = users.union(members) result = users if not membersonly: query = dict( portal_type='Contact', path='/'.join(workspace.getPhysicalPath()), sort_on='sortable_title') for brain in catalog(query): result.add(brain.UID) return PrincipalVocabulary(result)
def getClosestDestination(self): """Get the "closest translated object" URL. """ # We sould travel the parent chain using the catalog here, # but I think using the acquisition chain is faster # (or well, __parent__ pointers) because the catalog # would require a lot of queries, while technically, # having done traversal up to this point you should # have the objects in memory already # As we don't have any content object we are going to look # for the best option site = getSite() root = getToolByName(site, 'portal_url') ltool = getToolByName(site, 'portal_languages') # We are useing TranslationManager to get the translations of a # string tg manager = TranslationManager(self.tg) context = None languages = manager.get_translations() if len(languages) == 0: # If there is no results there are no translations # we move to portal root return self.wrapDestination(root(), postpath=False) # We are going to see if there is the prefered language translation # Otherwise we get the first as context to look for translation prefered = ltool.getPreferredLanguage() if prefered in languages: context = languages[prefered] else: context = languages[languages.keys()[0]] checkPermission = getSecurityManager().checkPermission chain = self.getParentChain(context) for item in chain: if ISiteRoot.providedBy(item) \ and not ILanguageRootFolder.providedBy(item): # We do not care to get a permission error # if the whole of the portal cannot be viewed. # Having a permission issue on the root is fine; # not so much for everything else so that is checked there return self.wrapDestination(item.absolute_url()) elif IFactoryTempFolder.providedBy(item) or \ IFactoryTool.providedBy(item): # TempFolder or portal_factory, can't have a translation continue try: canonical = ITranslationManager(item) except TypeError: if not ITranslatable.providedBy(item): # In case there it's not translatable go to parent # This solves the problem when a parent is not # ITranslatable continue else: raise translation = canonical.get_translation(self.lang) if translation and ( INavigationRoot.providedBy(translation) or bool(checkPermission('View', translation)) ): # Not a direct translation, therefore no postpath # (the view might not exist on a different context) return self.wrapDestination(translation.absolute_url(), postpath=False) # Site root's the fallback return self.wrapDestination(root(), postpath=False)
def _get_translations_by_closest(self, supported_langs): """ Return the translations information by figuring out the 'closest' translation in the parent chain of the context. We stop at both an INavigationRoot or an ISiteRoot to look for translations. We do want to find something that is definitely in the language the user asked for regardless anything else. """ context = aq_inner(self.context) missing = set([str(c) for c in supported_langs]) translations = {} chain = aq_chain(context) first_pass = True _checkPermission = getSecurityManager().checkPermission for item in chain: if ISiteRoot.providedBy(item): # We have a site root, which works as a fallback has_view_permission = bool(_checkPermission('View', item)) for c in missing: translations[c] = (item, first_pass, has_view_permission) break elif IFactoryTempFolder.providedBy(item) or \ IFactoryTool.providedBy(item): # TempFolder or portal_factory, can't have a translation continue try: canonical = ITranslationManager(item) except TypeError: if not ITranslatable.providedBy(item): # In case there it's not translatable go to parent # This solves the problem when a parent is not ITranslatable continue else: raise item_trans = canonical.get_translations() for code, trans in item_trans.items(): code = str(code) if code not in translations: # make a link to a translation only if the user # has view permission has_view_permission = bool(_checkPermission('View', trans)) if (not INavigationRoot.providedBy(item) and not has_view_permission): continue # If we don't yet have a translation for this language # add it and mark it as found translations[code] = (trans, first_pass, has_view_permission) missing = missing - set((code, )) if len(missing) <= 0: # We have translations for all break if INavigationRoot.providedBy(item): # Don't break out of the navigation root jail has_view_permission = bool(_checkPermission('View', item)) for c in missing: translations[c] = (item, False, has_view_permission) break first_pass = False # return a dict of language code to tuple. the first tuple element is # the translated object, the second argument indicates wether the # translation is a direct translation of the context or something from # higher up the translation chain return translations