Last modified by superadmin on 2025/05/22 17:45

Show last authors
1 {{velocity output='false'}}
2 #*
3 * Recursively retrieve the all that subgroups of a group.
4 *
5 * @param baseGroupDocument input group document. This can be a group from another wiki, other than the current one.
6 * @param visitedGroupDocuments output list of group document instances that are directly or indirectly subgroups of the input one. Also, this list is limited to groups that are located in the same wiki as the input one.
7 *#
8 #macro (getAllSubGroupsRecursively $baseGroupDocument $visitedGroupDocuments)
9 #if ($visitedGroupDocuments.contains($baseGroupDocument))
10 ## Already visited, skip and avoid cycles.
11 #break
12 #end
13 ## Mark the base group as visited to avoid going trough it twice.
14 #set ($discard = $visitedGroupDocuments.add($baseGroupDocument))
15 ##
16 ## Get the base group's members.
17 #set ($groupMemberObjects = $baseGroupDocument.getObjects('XWiki.XWikiGroups'))
18 ##
19 #foreach ($groupMemberObject in $groupMemberObjects)
20 #set ($groupMember = $groupMemberObject.getProperty('member').value)
21 #set ($groupMemberReference = $services.model.resolveDocument($groupMember))
22 ## Check if the member was specified relatively (no wiki prefix) and it was mistakingly resolved as local to the current wiki. Force to use the base group document's wiki name.
23 #if ("$!{groupMemberReference.wikiReference.name}" == $xcontext.database && !$groupMember.startsWith("${xcontext.database}:"))
24 #set ($groupMemberReference = $services.model.createDocumentReference($baseGroupDocument.documentReference.wikiReference.name, $groupMemberReference.lastSpaceReference.name, $groupMemberReference.name))
25 #end
26 ## Handle only members from the base group's wiki (ignore references to other members from other wikis).
27 #if ("$!{groupMemberReference.wikiReference}" == $baseGroupDocument.documentReference.wikiReference)
28 #set ($groupMemberDocument = $xwiki.getDocument($groupMemberReference))
29 ## Skip users, handle only subgroups.
30 #if ($groupMemberDocument.getObject('XWiki.XWikiGroups'))
31 ## Recursivity is recursive.
32 #getAllSubGroupsRecursively($groupMemberDocument, $visitedGroupDocuments)
33 #end
34 #end
35 #end
36 #end
37 #if($request.userScope == 'global')
38 #set ($currentWiki = $services.wiki.currentWikiId)
39 ##
40 ## Enhance the livetable query to return all the global users that are either directly or indirectly members of the wiki.
41 ##
42 #set ($extraFromClause = '')
43 #set ($extraWhereClause = '')
44 #set ($extraWhereClauseParameters = {})
45 ##
46 ## Step1: Get the wiki members from the wiki's members group.
47 #set ($wikiMembers = $services.wiki.user.getMembers($currentWiki))
48 ##
49 ## Differentiate between users and groups
50 #set ($wikiMemberUsers = [])
51 #set ($wikiMemberGroups = [])
52 #foreach ($wikiMember in $wikiMembers)
53 #set ($wikiMemberReference = $services.model.resolveDocument($wikiMember))
54 ## We are interested only in main wiki users and groups.
55 #set ($wikiMemberDocument = $xwiki.getDocument($wikiMemberReference))
56 ## A document can represent both a user and a group.
57 ## Is it a global user?
58 #if ($wikiMemberDocument.getObject('XWiki.XWikiUsers') && $wikiMember.startsWith("${services.wiki.mainWikiId}:"))
59 #set ($discard = $wikiMemberUsers.add($wikiMember))
60 #end
61 ## Is it a group?
62 #if ($wikiMemberDocument.getObject('XWiki.XWikiGroups'))
63 ## Recursively get all referenced groups from the main wiki.
64 #getAllSubGroupsRecursively($wikiMemberDocument, $wikiMemberGroups)
65 #end
66 #end
67 ##
68 ## Extend the livetable query to display only the direct users of the wiki and the indirect users (that are members of subgroups of the wiki group)
69 #if ($wikiMemberUsers.size() > 0 || $wikiMemberGroups.size() > 0)
70 #set ($extraWhereClause = "AND ")
71 #if ($wikiMemberUsers.size() > 0 && $wikiMemberGroups.size() > 0)
72 ## Begin both clauses group
73 #set ($extraWhereClause = "${extraWhereClause}(")
74 #end
75 ##
76 ## Users
77 #if ($wikiMemberUsers.size() > 0)
78 #set ($extraWhereClause = "${extraWhereClause}CONCAT('${services.wiki.mainWikiId}:', doc.fullName) IN (")
79 #foreach ($wikiMemberUser in $wikiMemberUsers)
80 #if ($foreach.count > 1)
81 #set ($extraWhereClause = "${extraWhereClause},")
82 #end
83 #set ($extraWhereClause = "${extraWhereClause}:wikiMemberUser_${foreach.count}")
84 #set ($discard = $extraWhereClauseParameters.put("wikiMemberUser_${foreach.count}", "$!{wikiMemberUser}"))
85 #end
86 #set ($extraWhereClause = "${extraWhereClause})")
87 #end
88 ## Groups
89 #if ($wikiMemberGroups.size() > 0)
90 #if ($wikiMemberUsers.size() > 0)
91 ## This is grouped with the users clause from above.
92 #set ($extraWhereClause = "${extraWhereClause} OR ")
93 #end
94 #set ($extraWhereClause = "${extraWhereClause}doc.fullName IN (SELECT prop.value FROM BaseObject as obj, StringProperty as prop WHERE obj.className='XWiki.XWikiGroups' AND prop.id.id=obj.id AND prop.name='member' AND obj.name IN (")
95 #foreach ($wikiMemberGroup in $wikiMemberGroups)
96 #if ($foreach.count > 1)
97 #set ($extraWhereClause = "${extraWhereClause},")
98 #end
99 #set ($extraWhereClause = "${extraWhereClause}:wikiMemberGroup_${foreach.count}")
100 #set ($discard = $extraWhereClauseParameters.put("wikiMemberGroup_${foreach.count}", "$!{wikiMemberGroup.fullName}"))
101 #end
102 #set ($extraWhereClause = "${extraWhereClause}))")
103 #end
104 ##
105 ## Close both clauses group
106 #if ($wikiMemberUsers.size() > 0 && $wikiMemberGroups.size() > 0)
107 #set ($extraWhereClause = "${extraWhereClause})")
108 #end
109 ## Step2: Set the database to the main wiki so that the query will be performed on the right wiki.
110 #set ($discard = $xcontext.setDatabase($services.wiki.mainWikiId))
111 #end
112 #end
113 {{/velocity}}
114
115 {{comment}}Call the default user directory data source that we have just enhanced.{{/comment}}
116
117 {{include reference='XWiki.UserDirectoryLivetableResults' /}}
118
119 {{velocity output='false'}}
120 #if($request.userScope == 'global')
121 ## Reset the context database to the initial one, in case this page gets included somewhere.
122 #set ($discard = $xcontext.setDatabase($currentWiki))
123 #end
124 {{/velocity}}