예제 #1
0
 def get_data(self):
     """Get json data to render the fancy tree."""
     query = self.get_query()
     strategy = NavtreeStrategyBase()
     strategy.rootPath = self.root_path
     folder_tree = buildFolderTree(self.portal, None, query, strategy)
     return json.dumps(self.folder_tree_to_fancytree(folder_tree))
예제 #2
0
파일: views.py 프로젝트: IMIO/imio.helpers
 def get_data(self):
     """Get json data to render the fancy tree."""
     query = self.get_query()
     strategy = NavtreeStrategyBase()
     strategy.rootPath = self.root_path
     folder_tree = buildFolderTree(self.portal, None, query, strategy)
     return json.dumps(self.folder_tree_to_fancytree(folder_tree))
예제 #3
0
파일: testNavTree.py 프로젝트: dtgit/dtedu
 def testGetFromRootWithSpecifiedRoot(self):
     rootPath = '/'.join(self.portal.getPhysicalPath())
     strategy = NavtreeStrategyBase()
     strategy.rootPath = rootPath + '/folder1'
     tree = buildFolderTree(self.portal, strategy=strategy)['children']
     self.assertEqual(len(tree), 3)
     self.assertEqual(tree[0]['item'].getPath(), rootPath + '/folder1/doc11')
     self.assertEqual(tree[1]['item'].getPath(), rootPath + '/folder1/doc12')
     self.assertEqual(tree[2]['item'].getPath(), rootPath + '/folder1/doc13')
예제 #4
0
 def testGetFromRootWithSpecifiedRoot(self):
     rootPath = '/'.join(self.portal.getPhysicalPath())
     strategy = NavtreeStrategyBase()
     strategy.rootPath = rootPath + '/folder1'
     tree = buildFolderTree(self.portal, strategy=strategy)['children']
     self.assertEqual(len(tree), 3)
     self.assertEqual(tree[0]['item'].getPath(), rootPath + '/folder1/doc11')
     self.assertEqual(tree[1]['item'].getPath(), rootPath + '/folder1/doc12')
     self.assertEqual(tree[2]['item'].getPath(), rootPath + '/folder1/doc13')
예제 #5
0
 def testShowAllParentsWithParentNotInCatalog(self):
     strategy = NavtreeStrategyBase()
     strategy.showAllParents = True
     self.portal.folder1.unindexObject()
     query = {'portal_type': 'Folder'}
     context = self.portal.folder1.doc11
     tree = buildFolderTree(self.portal, query=query, obj=context,
                            strategy=strategy)['children']
     rootPath = '/'.join(self.portal.getPhysicalPath())
     # XXX: Ideally, this shouldn't happen, we should get a dummy node, but
     # there's no way to do that with the catalog
     self.assertEqual(len(tree), 1)
     self.assertEqual(tree[0]['item'].getPath(), rootPath + '/folder2')
예제 #6
0
파일: testNavTree.py 프로젝트: dtgit/dtedu
 def testDontShowAllParents(self):
     strategy = NavtreeStrategyBase()
     strategy.showAllParents = False
     query = {'portal_type' : 'Folder'}
     context = self.portal.folder1.doc11
     tree = buildFolderTree(self.portal, query=query, obj=context, strategy=strategy)['children']
     rootPath = '/'.join(self.portal.getPhysicalPath())
     self.assertEqual(len(tree), 2)
     self.assertEqual(tree[0]['item'].getPath(), rootPath + '/folder1')
     self.assertEqual(len(tree[0]['children']), 0)
     self.assertEqual(tree[1]['item'].getPath(), rootPath + '/folder2')
     self.assertEqual(len(tree[1]['children']), 1)
     self.assertEqual(tree[1]['children'][0]['item'].getPath(), rootPath + '/folder2/folder21')
예제 #7
0
 def testDontShowAllParents(self):
     strategy = NavtreeStrategyBase()
     strategy.showAllParents = False
     query = {'portal_type' : 'Folder'}
     context = self.portal.folder1.doc11
     tree = buildFolderTree(self.portal, query=query, obj=context, strategy=strategy)['children']
     rootPath = '/'.join(self.portal.getPhysicalPath())
     self.assertEqual(len(tree), 2)
     self.assertEqual(tree[0]['item'].getPath(), rootPath + '/folder1')
     self.assertEqual(len(tree[0]['children']), 0)
     self.assertEqual(tree[1]['item'].getPath(), rootPath + '/folder2')
     self.assertEqual(len(tree[1]['children']), 1)
     self.assertEqual(tree[1]['children'][0]['item'].getPath(), rootPath + '/folder2/folder21')
예제 #8
0
 def testShowAllParentsWithParentNotInCatalog(self):
     strategy = NavtreeStrategyBase()
     strategy.showAllParents = True
     wftool = getToolByName(self.portal, 'portal_workflow')
     self.portal.folder1.unindexObject()
     query = {'portal_type' : 'Folder'}
     context = self.portal.folder1.doc11
     tree = buildFolderTree(self.portal, query=query, obj=context, strategy=strategy)['children']
     rootPath = '/'.join(self.portal.getPhysicalPath())
     # XXX: Ideally, this shouldn't happen, we should get a dummy node, but
     # there's no way to do that with the catalog
     self.assertEqual(len(tree), 1)
     self.assertEqual(tree[0]['item'].getPath(), rootPath + '/folder2')
예제 #9
0
파일: testNavTree.py 프로젝트: dtgit/dtedu
 def testShowAllParentsOverridesNonFolderishObjectNotExpanded(self):
     strategy = NavtreeStrategyBase()
     strategy.showAllParents = True
     self.setRoles(['Manager'])
     f = DummyNonStructuralFolder('ns_folder')
     self.portal._setObject('ns_folder', f)
     ns_folder = self.portal.ns_folder
     self.portal.portal_catalog.indexObject(self.portal.ns_folder)
     ns_folder.invokeFactory('Document', 'doc')
     self.setRoles(['Member'])
     tree = buildFolderTree(self.portal, self.portal.ns_folder.doc, strategy=strategy)['children']
     rootPath = '/'.join(self.portal.getPhysicalPath())
     self.assertEqual(tree[-1]['item'].getPath(), rootPath + '/ns_folder')
     self.assertEqual(len(tree[-1]['children']), 1)
     self.assertEqual(tree[-1]['children'][0]['item'].getPath(), rootPath + '/ns_folder/doc')
예제 #10
0
 def testShowAllParentsOverridesNonFolderishObjectNotExpanded(self):
     strategy = NavtreeStrategyBase()
     strategy.showAllParents = True
     self.setRoles(['Manager'])
     f = DummyNonStructuralFolder('ns_folder')
     self.portal._setObject('ns_folder', f)
     ns_folder = self.portal.ns_folder
     self.portal.portal_catalog.indexObject(self.portal.ns_folder)
     ns_folder.invokeFactory('Document', 'doc')
     self.setRoles(['Member'])
     tree = buildFolderTree(self.portal, self.portal.ns_folder.doc, strategy=strategy)['children']
     rootPath = '/'.join(self.portal.getPhysicalPath())
     self.assertEqual(tree[-1]['item'].getPath(), rootPath + '/ns_folder')
     self.assertEqual(len(tree[-1]['children']), 1)
     self.assertEqual(tree[-1]['children'][0]['item'].getPath(), rootPath + '/ns_folder/doc')
예제 #11
0
    def getCourseItemsInOrder(self):
        """
            Create a flattened out list of portal_catalog queried items in their natural depth first navigation order.
            @param root: Content item which acts as a navigation root
            @param query: Dictionary of portal_catalog query parameters
            @return: List of catalog brains
        """
        root = self
        possible_types = [
            'Kurs', 'Kursabschluss', 'Lerneinheit', 'Document', 'Aufgabe',
            'Audiovideo', 'Checkliste', 'Skill'
        ]
        query = {'portal_type': possible_types}

        # Navigation tree base portal_catalog query parameters
        applied_query = {
            'path': '/'.join(root.getPhysicalPath()),
            'sort_on': 'getObjPositionInParent'
        }

        # Apply caller's filters
        applied_query.update(query)

        # Set the navigation tree build strategy
        # - use navigation portlet strategy as base
        #strategy = DefaultNavtreeStrategy(root)
        strategy = NavtreeStrategyBase()
        strategy.rootPath = '/'.join(root.getPhysicalPath())
        strategy.showAllParents = False
        strategy.bottomLevel = 999
        # This will yield out tree of nested dicts of
        # item brains with retrofitted navigational data
        tree = buildFolderTree(root, root, query, strategy=strategy)

        items = []

        def flatten(children):
            """ Recursively flatten the tree """
            for c in children:
                # Copy catalog brain object into the result
                items.append(c["item"])
                children = c.get("children", None)
                if children:
                    flatten(children)

        flatten(tree["children"])
        return items
예제 #12
0
파일: testNavTree.py 프로젝트: dtgit/dtedu
 def testShowAllParentsWithRestrictedParent(self):
     strategy = NavtreeStrategyBase()
     strategy.showAllParents = True
     wftool = getToolByName(self.portal, 'portal_workflow')
     wftool.doActionFor(self.portal.folder1, 'hide')
     self.portal.folder1.reindexObject()
     query = {'portal_type' : 'Folder'}
     context = self.portal.folder1.doc11
     tree = buildFolderTree(self.portal, query=query, obj=context, strategy=strategy)['children']
     rootPath = '/'.join(self.portal.getPhysicalPath())
     self.assertEqual(len(tree), 2)
     self.assertEqual(tree[0]['item'].getPath(), rootPath + '/folder1')
     self.assertEqual(len(tree[0]['children']), 1)
     self.assertEqual(tree[0]['children'][0]['item'].getPath(), rootPath + '/folder1/doc11')
     self.assertEqual(tree[1]['item'].getPath(), rootPath + '/folder2')
     self.assertEqual(len(tree[1]['children']), 1)
     self.assertEqual(tree[1]['children'][0]['item'].getPath(), rootPath + '/folder2/folder21')
예제 #13
0
 def _getTemplatesTree(self):
     '''Create the structure of elements used to display the item templates tree to the item creators.
        We only want to show folders and items the current creator may use, so we do that in 2 steps :
        - a first catalog query that will find every items the creator may use,
          when found, we save the differents paths to these items so we will be able to
          not take into account folder that could exist in the configuration but that would
          be empty because no items into it;
        - when the query is build with list of paths to consider, we use buildFolderTree
          that will build a 'tree' dict with elements and children.'''
     # first query the catalog to see wich items the current user may select
     itemTemplatesPath = '/'.join(self.cfg.itemtemplates.getPhysicalPath())
     itemTemplates = self.cfg.getItemTemplates(as_brains=True,
                                               onlyActive=True,
                                               filtered=True)
     # we need to keep the itemTemplatesPath
     folderPathsToKeep = [
         itemTemplatesPath,
     ]
     # now compute folder paths so only these paths will be passed to buildFolderTree
     # and this method will not consider any other folders
     for itemTemplate in itemTemplates:
         folderPath = '/'.join(itemTemplate.getPath().split('/')[0:-1])
         # keep every folders of folderPath in case the itemtemplate is in a sub/sub/sub/...folder
         while folderPath not in folderPathsToKeep:
             folderPathsToKeep.append(folderPath)
             folderPath = '/'.join(folderPath.split('/')[0:-1])
     query = self.cfg._itemTemplatesQuery(onlyActive=True, filtered=True)
     # we want to query every Folders too
     query['portal_type'] = (query['portal_type'], 'Folder')
     query['path'] = {'query': folderPathsToKeep, 'depth': 1}
     # define a strategy so rootPath is managed ourself or folderTree
     # fails to compute it because query['path']['query'] is a list here...
     strategy = NavtreeStrategyBase()
     strategy.rootPath = itemTemplatesPath
     folderTree = buildFolderTree(self.context, None, query, strategy)
     # the single left problem is the fact that we could have empty folders
     # because we look in the itemTemplatesPath and it returns 'directly contained items' and
     # folders, we can not do anything else using a catalog query...
     # so check children of the root level, if it is an empty folder, we remove it...
     childrenToKeep = []
     for child in folderTree['children']:
         if child['item'].portal_type == 'Folder' and not child['children']:
             continue
         childrenToKeep.append(child)
     folderTree['children'] = childrenToKeep
     return folderTree
예제 #14
0
 def testShowAllParentsWithRestrictedParent(self):
     strategy = NavtreeStrategyBase()
     strategy.showAllParents = True
     wftool = getToolByName(self.portal, 'portal_workflow')
     wftool.doActionFor(self.portal.folder1, 'hide')
     self.portal.folder1.reindexObject()
     query = {'portal_type' : 'Folder'}
     context = self.portal.folder1.doc11
     tree = buildFolderTree(self.portal, query=query, obj=context, strategy=strategy)['children']
     rootPath = '/'.join(self.portal.getPhysicalPath())
     self.assertEqual(len(tree), 2)
     self.assertEqual(tree[0]['item'].getPath(), rootPath + '/folder1')
     self.assertEqual(len(tree[0]['children']), 1)
     self.assertEqual(tree[0]['children'][0]['item'].getPath(), rootPath + '/folder1/doc11')
     self.assertEqual(tree[1]['item'].getPath(), rootPath + '/folder2')
     self.assertEqual(len(tree[1]['children']), 1)
     self.assertEqual(tree[1]['children'][0]['item'].getPath(), rootPath + '/folder2/folder21')
예제 #15
0
def buildFolderTree(context,
                    obj=None,
                    query=None,
                    strategy=NavtreeStrategyBase()):
    """Create a tree structure representing a navigation tree. By default,
    it will create a full "sitemap" tree, rooted at the portal, ordered
    by explicit folder order. If the 'query' parameter contains a 'path'
    key, this can be used to override this. To create a navtree rooted
    at the portal root, set query['path'] to:

        {'query' : '/'.join(context.getPhysicalPath()),
         'navtree' : 1}

    to start this 1 level below the portal root, set query['path'] to:

        {'query' : '/'.join(obj.getPhysicalPath()),
         'navtree' : 1,
         'navtree_start' : 1}

    to create a sitemap with depth limit 3, rooted in the portal:

        {'query' : '/'.join(obj.getPhysicalPath()),
         'depth' : 3}

    The parameters:

    - 'context' is the acquisition context, from which tools will be acquired
    - 'obj' is the current object being displayed.
    - 'query' is a catalog query to apply to find nodes in the tree.
    - 'strategy' is an object that can affect how the generation works. It
        should be derived from NavtreeStrategyBase, if given, and contain:

            rootPath -- a string property; the physical path to the root node.

            If not given, it will default to any path set in the query, or the
            portal root. Note that in a navtree query, the root path will
            default to the portal only, possibly adjusted for any navtree_start
            set. If rootPath points to something not returned by the query by
            the query, a dummy node containing only an empty 'children' list
            will be returned.

            showAllParents -- a boolean property; if true and obj is given,
                ensure that all parents of the object, including any that would
                normally be filtered out are included in the tree.

            nodeFilter(node) -- a method returning a boolean; if this returns
                False, the given node will not be inserted in the tree

            subtreeFilter(node) -- a method returning a boolean; if this returns
                False, the given (folderish) node will not be expanded (its
                children will be pruned off)

            decoratorFactory(node) -- a method returning a dict; this can inject
                additional keys in a node being inserted.

            showChildrenOf(object) -- a method returning True if children of
                the given object (normally the root) should be returned

    Returns tree where each node is represented by a dict:

        item            -   A catalog brain of this item
        depth           -   The depth of this item, relative to the
                            startAt level
        currentItem     -   True if this is the current item
        currentParent   -   True if this is a direct parent of the current item
        children        -   A list of children nodes of this node

    Note: Any 'decoratorFactory' specified may modify this list, but
    the 'children' property is guaranteed to be there.

    Note: If the query does not return the root node itself, the root
    element of the tree may contain *only* the 'children' list.

    Note: Folder default-pages are not included in the returned result.
    If the 'obj' passed in is a default-page, its parent folder will be
    used for the purposes of selecting the 'currentItem'.
    """
    if not query:
        query = {}

    portal_url = getToolByName(context, 'portal_url')
    portal_catalog = getToolByName(context, 'portal_catalog')

    rootPath = strategy.rootPath

    # Find the object's path. Use parent folder if context is a default-page

    objPath = None
    objPhysicalPath = None
    if obj is not None:
        objPhysicalPath = obj.getPhysicalPath()
        objPath = '/'.join(objPhysicalPath)

    portalPath = portal_url.getPortalPath()
    portalObject = portal_url.getPortalObject()

    # Calculate rootPath from the path query if not set.

    if 'path' not in query:
        if rootPath is None:
            rootPath = portalPath
        query['path'] = rootPath
    elif rootPath is None:
        pathQuery = query['path']
        if isinstance(pathQuery, StringType):
            rootPath = pathQuery
        else:
            # Adjust for the fact that in a 'navtree' query, the actual path
            # is the path of the current context
            if pathQuery.get('navtree', False):
                navtreeLevel = pathQuery.get('navtree_start', 1)
                if navtreeLevel > 1:
                    navtreeContextPath = pathQuery['query']
                    navtreeContextPathElements = navtreeContextPath[
                        len(portalPath) + 1:].split('/')
                    # Short-circuit if we won't be able to find this path
                    if len(navtreeContextPathElements) < (navtreeLevel - 1):
                        return {'children': []}
                    rootPath = portalPath + '/' + '/'.join(
                        navtreeContextPathElements[:navtreeLevel - 1])
                else:
                    rootPath = portalPath
            else:
                rootPath = pathQuery['query']

    rootDepth = len(rootPath.split('/'))

    # Determine if we need to prune the root (but still force the path to)
    # the parent if necessary

    pruneRoot = False
    if strategy is not None:
        rootObject = portalObject.unrestrictedTraverse(rootPath, None)
        if rootObject is not None:
            pruneRoot = not strategy.showChildrenOf(rootObject)

    if 'sort_on' not in query:
        query['sort_on'] = 'getObjPositionInParent'

    results = portal_catalog.searchResults(query)

    # We keep track of a dict of item path -> node, so that we can easily
    # find parents and attach children. If a child appears before its
    # parent, we stub the parent node.

    # This is necessary because whilst the sort_on parameter will ensure
    # that the objects in a folder are returned in the right order relative
    # to each other, we don't know the relative order of objects from
    # different folders. So, if /foo comes before /bar, and /foo/a comes
    # before /foo/b, we may get a list like (/bar/x, /foo/a, /foo/b, /foo,
    # /bar,).

    itemPaths = {}

    # Add an (initially empty) node for the root
    itemPaths[rootPath] = {'children': []}

    # If we need to "prune" the parent (but still allow showAllParent to
    # force some children), do so now
    if pruneRoot:
        itemPaths[rootPath]['_pruneSubtree'] = True

    def insertElement(itemPaths, item, forceInsert=False):
        """Insert the given 'item' brain into the tree, which is kept in
        'itemPaths'. If 'forceInsert' is True, ignore node- and subtree-
        filters, otherwise any node- or subtree-filter set will be allowed to
        block the insertion of a node.
        """
        itemPath = item.getPath()
        itemInserted = (itemPaths.get(itemPath, {}).get('item', None)
                        is not None)

        # Short-circuit if we already added this item. Don't short-circuit
        # if we're forcing the insert, because we may have inserted but
        # later pruned off the node
        if not forceInsert and itemInserted:
            return

        itemPhysicalPath = itemPath.split('/')
        parentPath = '/'.join(itemPhysicalPath[:-1])
        parentPruned = (itemPaths.get(parentPath,
                                      {}).get('_pruneSubtree', False))

        # Short-circuit if we know we're pruning this item's parent

        # We could do this recursively, in case of parent of the
        # parent was being pruned, but this may not be a great trade-off

        # There is scope for more efficiency improvement here: If we knew we
        # were going to prune the subtree,
        # we would short-circuit here each time.
        # In order to know that, we'd have to make sure we inserted each parent
        # before its children, by sorting the catalog result set (probably
        # manually) to get a breadth-first search.

        if not forceInsert and parentPruned:
            return

        isCurrent = isCurrentParent = False
        if objPath is not None:
            if objPath == itemPath:
                isCurrent = True
            elif objPath.startswith(itemPath + '/') and len(
                    objPhysicalPath) > len(itemPhysicalPath):
                isCurrentParent = True

        isDefaultPage = getattr(item, 'is_default_page', False)

        relativeDepth = len(itemPhysicalPath) - rootDepth

        newNode = {
            'item': item,
            'depth': relativeDepth,
            'currentItem': isCurrent,
            'currentParent': isCurrentParent,
        }

        insert = True
        if not forceInsert and strategy is not None:
            insert = strategy.nodeFilter(newNode)
        if insert:

            if strategy is not None:
                newNode = strategy.decoratorFactory(newNode)

            # Tell parent about this item, unless an earlier subtree filter
            # told us not to. If we're forcing the insert, ignore the
            # pruning, but avoid inserting the node twice
            if parentPath in itemPaths:
                itemParent = itemPaths[parentPath]
                if forceInsert:
                    nodeAlreadyInserted = False
                    for i in itemParent['children']:
                        if i['item'].getPath() == itemPath:
                            nodeAlreadyInserted = True
                            break
                    if not nodeAlreadyInserted:
                        if isDefaultPage:
                            itemParent['children'].insert(0, newNode)
                        else:
                            itemParent['children'].append(newNode)
                elif not itemParent.get('_pruneSubtree', False):
                    if isDefaultPage:
                        itemParent['children'].insert(0, newNode)
                    else:
                        itemParent['children'].append(newNode)
            else:
                itemPaths[parentPath] = {'children': [newNode]}

            # Ask the subtree filter (if any), if we should
            # be expanding this node
            if strategy.showAllParents and isCurrentParent:
                # If we will be expanding this later, we
                # can't prune off children now
                expand = True
            else:
                expand = getattr(item, 'is_folderish', True)
            if expand and (not forceInsert and strategy is not None):
                expand = strategy.subtreeFilter(newNode)

            children = newNode.setdefault('children', [])
            if expand:
                # If we had some orphaned children for this node, attach
                # them
                if itemPath in itemPaths:
                    children.extend(itemPaths[itemPath]['children'])
            else:
                newNode['_pruneSubtree'] = True

            itemPaths[itemPath] = newNode

    # Add the results of running the query
    for r in results:
        insertElement(itemPaths, r)

    # If needed, inject additional nodes for the direct parents of the
    # context. Note that we use an unrestricted query: things we don't normally
    # have permission to see will be included in the tree.
    if strategy.showAllParents and objPath is not None:
        objSubPathElements = objPath[len(rootPath) + 1:].split('/')
        parentPaths = []

        haveNode = (itemPaths.get(rootPath, {}).get('item', None) is None)
        if not haveNode:
            parentPaths.append(rootPath)

        parentPath = rootPath
        for i in range(len(objSubPathElements)):
            nodePath = rootPath + '/' + '/'.join(objSubPathElements[:i + 1])
            node = itemPaths.get(nodePath, None)

            # If we don't have this node, we'll have to get it, if we have it
            # but it wasn't connected, re-connect it
            if node is None or 'item' not in node:
                parentPaths.append(nodePath)
            else:
                nodeParent = itemPaths.get(parentPath, None)
                if nodeParent is not None:
                    nodeAlreadyInserted = False
                    for j in nodeParent['children']:
                        if j['item'].getPath() == nodePath:
                            nodeAlreadyInserted = True
                            break
                    if not nodeAlreadyInserted:
                        nodeParent['children'].append(node)

            parentPath = nodePath

        # If we were outright missing some nodes, find them again
        if parentPaths:
            query = {'path': {'query': parentPaths, 'depth': 0}}
            results = portal_catalog.unrestrictedSearchResults(query)

            for r in results:
                insertElement(itemPaths, r, forceInsert=True)

    # Return the tree starting at rootPath as the root node.
    return itemPaths[rootPath]
예제 #16
0
def customBuildFolderTree(context, obj=None, query={}, strategy=NavtreeStrategyBase()):
    """
    """
    from plone import api
    from genweb.organs import utils as utilsOrgans

    portal_url = getToolByName(context, 'portal_url')
    portal_catalog = api.portal.get_tool(name='portal_catalog')

    showAllParents = strategy.showAllParents
    rootPath = strategy.rootPath

    request = getattr(context, 'REQUEST', {})

    # Find the object's path. Use parent folder if context is a default-page

    objPath = None
    objPhysicalPath = None
    if obj is not None:
        objPhysicalPath = obj.getPhysicalPath()
        if utils.isDefaultPage(obj, request):
            objPhysicalPath = objPhysicalPath[:-1]
        objPath = '/'.join(objPhysicalPath)

    portalPath = portal_url.getPortalPath()
    portalObject = portal_url.getPortalObject()

    # Calculate rootPath from the path query if not set.

    if 'path' not in query:
        if rootPath is None:
            rootPath = portalPath
        query['path'] = rootPath
    elif rootPath is None:
        pathQuery = query['path']
        if type(pathQuery) == StringType:
            rootPath = pathQuery
        else:
            # Adjust for the fact that in a 'navtree' query, the actual path
            # is the path of the current context
            if pathQuery.get('navtree', False):
                navtreeLevel = pathQuery.get('navtree_start', 1)
                if navtreeLevel > 1:
                    navtreeContextPath = pathQuery['query']
                    navtreeContextPathElements = navtreeContextPath[len(portalPath) + 1:].split('/')
                    # Short-circuit if we won't be able to find this path
                    if len(navtreeContextPathElements) < (navtreeLevel - 1):
                        return {'children': []}
                    rootPath = portalPath + '/' + '/'.join(navtreeContextPathElements[:navtreeLevel - 1])
                else:
                    rootPath = portalPath
            else:
                rootPath = pathQuery['query']

    rootDepth = len(rootPath.split('/'))

    # Determine if we need to prune the root (but still force the path to)
    # the parent if necessary

    pruneRoot = False
    if strategy is not None:
        rootObject = portalObject.unrestrictedTraverse(rootPath, None)
        if rootObject is not None:
            pruneRoot = not strategy.showChildrenOf(rootObject)

    # Allow the strategy to suppliment the query for keys not already
    # present in the query such as sorting and omitting default pages
    for key, value in strategy.supplimentQuery.iteritems():
        if key not in query:
            query[key] = value

    results2 = portal_catalog.searchResults(query)
    results = []
    from plone import api
    if api.user.is_anonymous():
        username = None
    else:
        username = api.user.get_current().id
    for value in results2:
        if value.portal_type == 'genweb.organs.organgovern':
            organ = value.getObject()
            if username:
                roles = api.user.get_roles(obj=organ, username=username)
            else:
                roles = []
            organType = organ.organType
            if 'Manager' in roles or (organType == 'open_organ'):
                results.append(value)
            elif organType == 'restricted_to_members_organ':
                if utilsOrgans.checkhasRol(['OG1-Secretari', 'OG2-Editor', 'OG3-Membre', 'OG5-Convidat'], roles):
                    results.append(value)
            elif organType == 'restricted_to_affected_organ':
                if utilsOrgans.checkhasRol(['OG1-Secretari', 'OG2-Editor', 'OG3-Membre', 'OG4-Afectat', 'OG5-Convidat'], roles):
                    results.append(value)
            else:
                # remove element
                continue
        else:
            results.append(value)

    # We keep track of a dict of item path -> node, so that we can easily
    # find parents and attach children. If a child appears before its
    # parent, we stub the parent node.

    # This is necessary because whilst the sort_on parameter will ensure
    # that the objects in a folder are returned in the right order relative
    # to each other, we don't know the relative order of objects from
    # different folders. So, if /foo comes before /bar, and /foo/a comes
    # before /foo/b, we may get a list like (/bar/x, /foo/a, /foo/b, /foo,
    # /bar,).

    itemPaths = {}

    # Add an (initially empty) node for the root
    itemPaths[rootPath] = {'children': []}

    # If we need to "prune" the parent (but still allow showAllParent to
    # force some children), do so now
    if pruneRoot:
        itemPaths[rootPath]['_pruneSubtree'] = True

    def insertElement(itemPaths, item, forceInsert=False):
        """Insert the given 'item' brain into the tree, which is kept in
        'itemPaths'. If 'forceInsert' is True, ignore node- and subtree-
        filters, otherwise any node- or subtree-filter set will be allowed to
        block the insertion of a node.
        """
        itemPath = item.getPath()
        itemInserted = (itemPaths.get(itemPath, {}).get('item', None) is not None)

        # Short-circuit if we already added this item. Don't short-circuit
        # if we're forcing the insert, because we may have inserted but
        # later pruned off the node
        if not forceInsert and itemInserted:
            return

        itemPhysicalPath = itemPath.split('/')
        parentPath = '/'.join(itemPhysicalPath[:-1])
        parentPruned = (itemPaths.get(parentPath, {}).get('_pruneSubtree', False))

        # Short-circuit if we know we're pruning this item's parent

        # XXX: We could do this recursively, in case of parent of the
        # parent was being pruned, but this may not be a great trade-off

        # There is scope for more efficiency improvement here: If we knew we
        # were going to prune the subtree, we would short-circuit here each time.
        # In order to know that, we'd have to make sure we inserted each parent
        # before its children, by sorting the catalog result set (probably
        # manually) to get a breadth-first search.

        if not forceInsert and parentPruned:
            return

        isCurrent = isCurrentParent = False
        if objPath is not None:
            if objPath == itemPath:
                isCurrent = True
            elif objPath.startswith(itemPath + '/') and len(objPhysicalPath) > len(itemPhysicalPath):
                isCurrentParent = True

        relativeDepth = len(itemPhysicalPath) - rootDepth

        newNode = {'item': item,
                   'depth': relativeDepth,
                   'currentItem': isCurrent,
                   'currentParent': isCurrentParent, }

        insert = True
        if not forceInsert and strategy is not None:
            insert = strategy.nodeFilter(newNode)
        if insert:

            if strategy is not None:
                newNode = strategy.decoratorFactory(newNode)

            # Tell parent about this item, unless an earlier subtree filter
            # told us not to. If we're forcing the insert, ignore the
            # pruning, but avoid inserting the node twice
            if parentPath in itemPaths:
                itemParent = itemPaths[parentPath]
                if forceInsert:
                    nodeAlreadyInserted = False
                    for i in itemParent['children']:
                        if i['item'].getPath() == itemPath:
                            nodeAlreadyInserted = True
                            break
                    if not nodeAlreadyInserted:
                        itemParent['children'].append(newNode)
                elif not itemParent.get('_pruneSubtree', False):
                    itemParent['children'].append(newNode)
            else:
                itemPaths[parentPath] = {'children': [newNode]}

            # Ask the subtree filter (if any), if we should be expanding this node
            if strategy.showAllParents and isCurrentParent:
                # If we will be expanding this later, we can't prune off children now
                expand = True
            else:
                expand = getattr(item, 'is_folderish', True)
            if expand and (not forceInsert and strategy is not None):
                expand = strategy.subtreeFilter(newNode)

            children = newNode.setdefault('children', [])
            if expand:
                # If we had some orphaned children for this node, attach
                # them
                if itemPath in itemPaths:
                    children.extend(itemPaths[itemPath]['children'])
            else:
                newNode['_pruneSubtree'] = True

            itemPaths[itemPath] = newNode

    # Add the results of running the query
    for r in results:
        insertElement(itemPaths, r)

    # If needed, inject additional nodes for the direct parents of the
    # context. Note that we use an unrestricted query: things we don't normally
    # have permission to see will be included in the tree.
    if strategy.showAllParents and objPath is not None:
        objSubPathElements = objPath[len(rootPath) + 1:].split('/')
        parentPaths = []

        haveNode = (itemPaths.get(rootPath, {}).get('item', None) is None)
        if not haveNode:
            parentPaths.append(rootPath)

        parentPath = rootPath
        for i in range(len(objSubPathElements)):
            nodePath = rootPath + '/' + '/'.join(objSubPathElements[:i + 1])
            node = itemPaths.get(nodePath, None)

            # If we don't have this node, we'll have to get it, if we have it
            # but it wasn't connected, re-connect it
            if node is None or 'item' not in node:
                parentPaths.append(nodePath)
            else:
                nodeParent = itemPaths.get(parentPath, None)
                if nodeParent is not None:
                    nodeAlreadyInserted = False
                    for i in nodeParent['children']:
                        if i['item'].getPath() == nodePath:
                            nodeAlreadyInserted = True
                            break
                    if not nodeAlreadyInserted:
                        nodeParent['children'].append(node)

            parentPath = nodePath

        # If we were outright missing some nodes, find them again
        if len(parentPaths) > 0:
            query = {'path': {'query': parentPaths, 'depth': 0}}
            results = portal_catalog.unrestrictedSearchResults(query)

            for r in results:
                insertElement(itemPaths, r, forceInsert=True)

    # Return the tree starting at rootPath as the root node.
    return itemPaths[rootPath]