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

Hide last authors
superadmin 1.1 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 workspace. 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 ##
38 ##
39 ## If this is a workspace, there are no local users so we are interested only in global users.
40 #set ($currentDatabase = $xcontext.database)
41 #if ($services.workspace.isWorkspace($currentDatabase))
42 ##
43 ## Enhance the livetable query to return all the global users that are either directly or indirectly members of the workspace.
44 ##
45 #set ($extraFromClause = '')
46 #set ($extraWhereClause = '')
47 #set ($extraWhereClauseParameters = {})
48 ##
49 ## Step1: Get the workspace members from the workspace's members group.
50 #set ($workspace = $services.workspace.getWorkspace($currentDatabase))
51 #set ($workspaceMemberObjects = $workspace.groupDocument.getObjects('XWiki.XWikiGroups'))
52 ##
53 ## Differentiate between users and groups
54 #set ($workspaceMemberUsers = [])
55 #set ($workspaceMemberGroups = [])
56 #foreach ($workspaceMemberObject in $workspaceMemberObjects)
57 #set ($workspaceMember = $workspaceMemberObject.getProperty('member').value)
58 #set ($workspaceMemberReference = $services.model.resolveDocument($workspaceMember))
59 ## We are interested only in main wiki users and groups, since we are in a workspace.
60 #if ("$!workspaceMemberReference.wikiReference.name" == $xcontext.mainWikiName)
61 #set ($workspaceMemberDocument = $xwiki.getDocument($workspaceMemberReference))
62 ## A document can represent both a user and a group.
63 ## Is it a user?
64 #if ($workspaceMemberDocument.getObject('XWiki.XWikiUsers'))
65 #set ($discard = $workspaceMemberUsers.add($workspaceMember))
66 #end
67 ## Is it a group?
68 #if ($workspaceMemberDocument.getObject('XWiki.XWikiGroups'))
69 ## Recursively get all referenced groups from the main wiki.
70 #getAllSubGroupsRecursively($workspaceMemberDocument, $workspaceMemberGroups)
71 #end
72 #end
73 #end
74 ##
75 ## Extend the livetable query to display only the direct users of the workspace and the indirect users (that are members of subgroups of the workspace group)
76 #if ($workspaceMemberUsers.size() > 0 || $workspaceMemberGroups.size() > 0)
77 #set ($extraWhereClause = "AND ")
78 #if ($workspaceMemberUsers.size() > 0 && $workspaceMemberGroups.size() > 0)
79 ## Begin both clauses group
80 #set ($extraWhereClause = "${extraWhereClause}(")
81 #end
82 ##
83 ## Users
84 #if ($workspaceMemberUsers.size() > 0)
85 #set ($extraWhereClause = "${extraWhereClause}CONCAT('${xcontext.mainWikiName}:', doc.fullName) IN (")
86 #foreach ($workspaceMemberUser in $workspaceMemberUsers)
87 #if ($foreach.count > 1)
88 #set ($extraWhereClause = "${extraWhereClause},")
89 #end
90 #set ($extraWhereClause = "${extraWhereClause}:workspaceMemberUser_${foreach.count}")
91 #set ($discard = $extraWhereClauseParameters.put("workspaceMemberUser_${foreach.count}", "$!{workspaceMemberUser}"))
92 #end
93 #set ($extraWhereClause = "${extraWhereClause})")
94 #end
95 ## Groups
96 #if ($workspaceMemberGroups.size() > 0)
97 #if ($workspaceMemberUsers.size() > 0)
98 ## This is grouped with the users clause from above.
99 #set ($extraWhereClause = "${extraWhereClause} OR ")
100 #end
101 #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 (")
102 #foreach ($workspaceMemberGroup in $workspaceMemberGroups)
103 #if ($foreach.count > 1)
104 #set ($extraWhereClause = "${extraWhereClause},")
105 #end
106 #set ($extraWhereClause = "${extraWhereClause}:workspaceMemberGroup_${foreach.count}")
107 #set ($discard = $extraWhereClauseParameters.put("workspaceMemberGroup_${foreach.count}", "$!{workspaceMemberGroup.fullName}"))
108 #end
109 #set ($extraWhereClause = "${extraWhereClause}))")
110 #end
111 ##
112 ## Close both clauses group
113 #if ($workspaceMemberUsers.size() > 0 && $workspaceMemberGroups.size() > 0)
114 #set ($extraWhereClause = "${extraWhereClause})")
115 #end
116 #end
117 ##
118 ## Step2: Set the database to the main wiki so that the query will be performed on the right wiki.
119 #set ($discard = $xcontext.setDatabase($xcontext.mainWikiName))
120 #end
121 {{/velocity}}
122
123 {{comment}}Call the default user directory data source that we have just enhanced.{{/comment}}
124
125 {{include reference='XWiki.UserDirectoryLivetableResults' /}}
126
127 {{velocity output='false'}}
128 ##
129 #if ($services.workspace.isWorkspace($xcontext.database))
130 ## Reset the context database to the initial one, in case this page gets included somewhere.
131 #set ($discard = $xcontext.setDatabase($currentDatabase))
132 #end
133 {{/velocity}}