Wiki-Quellcode von User Directory Macros

Zuletzt geändert von admin am 2023/07/25 15:00

Zeige letzte Bearbeiter
1 {{velocity output='false'}}
2 ## Users class
3 #set ($xwikiUsersClassReference = $services.model.createDocumentReference($xcontext.database, 'XWiki', 'XWikiUsers'))
4 #set ($xwikiUsersClass = $xwiki.getDocument($xwikiUsersClassReference).xWikiClass)
5 ## Configuration class
6 #set ($directoryPreferencesClassReference = $services.model.createDocumentReference($xcontext.database, 'XWiki', 'UserDirectoryPreferencesClass'))
7 #set ($directoryPreferencesClassName = $services.model.serialize($directoryPreferencesClassReference))
8 ## Default Configuration
9 #set ($defaultConfigurationDocReference = $services.model.createDocumentReference($xcontext.database, 'XWiki', 'UserDirectoryConfiguration'))
10 #set ($defaultConfigurationDoc = $xwiki.getDocument($defaultConfigurationDocReference))
11 #set ($defaultConfiguration = $defaultConfigurationDoc.getObject($directoryPreferencesClassName))
12
13 ## We use an ordered set to collect the live table columns because we want to avoid duplicates (they break the live
14 ## table filtering query) and at the same time we want to preserve the column order.
15 #set ($columns = $collectiontool.orderedSet)
16 ## Add the fixed columns that we want the user directory to always show.
17 #set ($discard = $columns.addAll(['_avatar', 'doc.name']))
18
19 ## Default configuration
20 ## The columns that the user directory will default to when no user preferences exist or when the user resets to default.
21 ## These defaults can be configured by the wiki's admins.
22 #set ($isGlobalUserDirectory = $doc.fullName != 'Main.UserDirectory')
23 #if ($isGlobalUserDirectory)
24 ## Fallback defaults.
25 #set ($defaultColumnsString = 'first_name last_name')
26 #else
27 ## Admin configured defaults.
28 #set ($defaultColumnsString = "$!defaultConfiguration.getValue('columns').trim()")
29 #end
30 #set ($defaultColumns = $defaultColumnsString.split('\s+'))
31
32 ## Current Configuration
33 #if ($isGlobalUserDirectory || $isGuest || $isSuperAdmin)
34 ## Use the default configuration when editing the default configuration itself or
35 ## when the current user doesn't have a profile document, so no preferences.
36 #set ($configurationDoc = $defaultConfigurationDoc)
37 #else
38 ## Use the current user's configuration
39 #set ($configurationDoc = $xwiki.getDocument($xcontext.userReference))
40 #end
41 ## Get or create the current configuration object, taking into account the values from the request (which is needed for
42 ## the live preview).
43 #set ($configuration = $configurationDoc.updateObjectFromRequest($directoryPreferencesClassName))
44
45 ## Read the configuration and initialize with defaults if necessary.
46 #set ($columnsString = $configuration.getValue('columns').trim())
47 #if ($columnsString == $NULL)
48 #set ($columnsString = $defaultColumnsString)
49 #set ($discard = $configuration.set('columns', $columnsString))
50 #end
51
52 ## Check if they are the default preferences.
53 #set ($isCustomized = false)
54 #if ($columnsString != $defaultColumnsString)
55 ## Mark it as a customized user directory.
56 #set ($isCustomized = true)
57 #end
58
59 ## Build the list of columns to display.
60 #foreach ($column in $columnsString.split('\s+'))
61 ## Skip invalid columns.
62 #if ($column.trim() != '' && $xwikiUsersClass.get($column))
63 #set ($discard = $columns.add($column))
64 #end
65 #end
66
67 ##
68 ## Build and display the resulting livetable, nothing else.
69 ##
70 #macro (displayUserDirectoryLiveTable)
71 {{html clean="false"}}
72 #set ($columnsProperties = {})
73 #foreach ($column in $columns)
74 #set ($columnProperties = {
75 'type': 'text',
76 'html': false,
77 'sortable': true,
78 'filterable': true,
79 'displayName': $xwikiUsersClass.get($column).translatedPrettyName
80 })
81 #set ($classPropertyType = $xwikiUsersClass.get($column).classType)
82 #if ($column == '_avatar')
83 #set ($discard = $columnProperties.putAll({
84 'html': true,
85 'sortable': false,
86 'filterable': false,
87 'link': 'view'
88 }))
89 #elseif ($column == 'doc.name')
90 #set ($columnProperties.link = 'view')
91 #elseif ($classPropertyType.endsWith('List'))
92 #set ($columnProperties.type = 'list')
93 #elseif ($classPropertyType.endsWith('Number'))
94 #set ($columnProperties.type = 'number')
95 #elseif ($classPropertyType.endsWith('Password'))
96 #set ($discard = $columnProperties.putAll({
97 'sortable': false,
98 'filterable': false
99 }))
100 #elseif ($classPropertyType.endsWith('TextArea') || $classPropertyType.endsWith('Email') || $classPropertyType.endsWith('Groups'))
101 #set ($columnProperties.html = true)
102 #end
103 #set ($discard = $columnsProperties.put($column, $columnProperties))
104 #end
105 ##
106 ## Allow other applications to provide a different data source for the user directory livetable. For example, some application might define a different membership relation.
107 #set ($userDirectoryLivetableResultsReference = $services.model.createDocumentReference($xcontext.database, 'XWiki', 'UserDirectoryLivetableResultsOverride'))
108 #if (!$xwiki.exists($userDirectoryLivetableResultsReference))
109 ## If no override is present, use the default data source.
110 #set ($userDirectoryLivetableResultsReference = $services.model.createDocumentReference($xcontext.database, 'XWiki', 'UserDirectoryLivetableResults'))
111 #end
112 ## Note that we specify the class name even though we use a custom results page (which hard-codes it) because the class
113 ## name is needed by the live table filters, to have a proper drop down list for Static List fields for instance
114 ## (see XWIKI-9660).
115 #set ($options = {
116 'className': $services.model.serialize($xwikiUsersClassReference, 'local'),
117 'resultPage' : "$services.model.serialize($userDirectoryLivetableResultsReference)",
118 'translationPrefix' : 'xe.userdirectory.',
119 'tagCloud' : true,
120 'rowCount': 10,
121 'outputOnlyHtml': true
122 })
123 ## Add a filter for subwikis
124 #if ($xcontext.database != $xcontext.mainWikiName && "$!services.wiki" != '' && "$!services.wiki.user" != '')
125 #set ($userScope = $services.wiki.user.getUserScope($services.wiki.currentWikiId))
126 #if ($userScope == 'GLOBAL_ONLY')
127 #set ($discard = $options.put('extraParams', 'userScope=global'))
128 #else
129 #set ($discard = $options.put('extraParams', 'userScope=local'))
130 #end
131 #if ($userScope == 'LOCAL_AND_GLOBAL')
132 <form class='xform third' action=''>
133 <dl>
134 <dt>
135 <label for='userScopeFilter'>$services.localization.render('userdirectory.userScopeFilter')</label>
136 <span class='xHint'>$services.localization.render('userdirectory.userScopeFilter.hint')</span>
137 </dt>
138 <dd>
139 <select name='userScope' id='userScopeFilter'>
140 <option value='local'>$services.localization.render('userdirectory.userScopeFilter.local')</option>
141 <option value='global'>$services.localization.render('userdirectory.userScopeFilter.global')</option>
142 </select>
143 </dd>
144 </dl>
145 </form>
146 #end
147 #end
148 ## We can't filter the values of the 'disabled' user profile property directly from the 'extraParams' live table
149 ## results option because we can't express 'not equal' (we need to say: include only the user profiles for which the
150 ## value of the 'disabled' property is not equal to 1). An user profile that doesn't have any value set for the
151 ## 'disabled' property is enabled.
152 ## We don't hide the disabled user profiles when the active and disabled columns are present because the user can use
153 ## the live table filters to achieve this.
154 #set ($hideDisabledProfilesValue = $configuration.getValue('hideDisabledProfiles'))
155 #if (!$columns.contains('active')
156 && ($hideDisabledProfilesValue == 1 || ("$!hideDisabledProfilesValue" == '' &&
157 $configuration.xWikiClass.get('hideDisabledProfiles').getValue('defaultValue') == 1)))
158 #set ($options.extraParams = "$!options.extraParams&hideDisabledProfiles=true")
159 #end
160 ## We need to know which users are disabled or inactive in order to display them differently.
161 #set ($discard = $columns.add('active'))
162 #set ($discard = $columnsProperties.putIfAbsent('active', {'type': 'hidden'}))
163 ## Display the computed livetable.
164 #livetable('userdirectory' $columns $columnsProperties $options)
165 {{/html}}
166 #end
167
168 ## xredirect value used to come back to the current URL when performing actions
169 #set ($xredirect = $doc.getURL($xcontext.action, $request.queryString))
170
171 ##
172 ## Displays the customization form and preview. Also handles the form's actions.
173 ##
174 #macro (displayUserDirectoryCustomizationForm)
175 #if (!$configurationDoc.hasAccessLevel('edit'))
176 {{error}}$services.localization.render('platform.userdirectory.customizeNotAllowed'){{/error}}
177 #else
178 #handleUserDirectoryAction()
179 ##
180 ## Customization form
181 ##
182 (% id="HUserDirectoryConfiguration" %)
183 == {{translation key="userdirectory.configuration.title"/}} ==
184 {{html clean="false"}}
185 <form class="user-directory-settings xform" action="$configurationDoc.getURL('save')" method="post">
186 <div class="hidden">
187 <input type="hidden" name="form_token" value="$escapetool.xml($services.csrf.token)" />
188 <input type="hidden" name="objectPolicy" value="updateOrCreate" />
189 <input type="hidden" name="xredirect" value="$escapetool.xml($xredirect)" />
190 <input type="hidden" name="comment" value="Updated user directory preferences" />
191 </div>
192 <dl>
193 #displayProperty('columns' $configuration 'edit')
194 #displayProperty('hideDisabledProfiles' $configuration 'edit')
195 </dl>
196 <p>
197 <input class="button" type="submit" name="action_save"
198 value="$escapetool.xml($services.localization.render('xe.userdirectory.customizeSaveButtonLabel'))"/>
199 #set ($resetQueryString = "$!request.queryString&" + $escapetool.url({
200 'action': 'reset',
201 'form_token': $services.csrf.token,
202 'xredirect': $xredirect
203 }))
204 #set ($resetURL = $doc.getURL($xcontext.action, $resetQueryString))
205 <a href="$escapetool.xml($resetURL)" class="button secondary">
206 $escapetool.xml($services.localization.render('xe.userdirectory.customizeResetButtonLabel'))
207 </a>
208 </p>
209 </form>
210 {{/html}}
211 #end
212 #end
213
214 #macro (handleUserDirectoryAction)
215 #if ("$!request.action" != '')
216 #if ($services.csrf.isTokenValid($request.form_token))
217 #if ($request.action == 'reset')
218 #if ($isGlobalUserDirectory)
219 ## For the global configuration it might be best to keep the object but set default values.
220 #set ($discard = $configuration.set('columns', $defaultColumnsString))
221 #else
222 ## For user preferences, just remove the object.
223 #set ($discard = $configurationDoc.removeObject($configuration))
224 #end
225 #set ($discard = $configurationDoc.save('Reset user directory preferences.'))
226 #end
227 ## Redirect using xredirect so that the page can be safely refreshed after an action.
228 #set ($discard = $response.sendRedirect($request.xredirect))
229 #elseif ($request.getHeader('X-Requested-With') == 'XMLHttpRequest')
230 #set ($discard = $response.sendError(401, 'CSRF token verification failed!'))
231 #else
232 #set ($discard = $response.sendRedirect($services.csrf.resubmissionURL))
233 #end
234 #stop()
235 #end
236 #end
237
238 #macro (displayProperty $propertyName $object $action)
239 #set ($propertyClass = $object.xWikiClass.get($propertyName))
240 #set ($isCheckbox = $propertyClass.getValue('displayFormType') == 'checkbox')
241 #set ($fieldDisplay = "#unwrapXPropertyDisplay($object.display($propertyName, $action))")
242 <dt>
243 <label #if ($action == 'edit' && !$isCheckbox)
244 for="$escapetool.xml("${object.xWikiClass.name}_${object.number}_$propertyName")"#end>
245 #if ($isCheckbox)
246 $fieldDisplay
247 #end
248 $escapetool.xml($propertyClass.translatedPrettyName)
249 </label>
250 <span class="xHint">
251 $!escapetool.xml($propertyClass.hint)
252 </span>
253 </dt>
254 <dd>#if (!$isCheckbox)$fieldDisplay#end</dd>
255 #end
256
257 ##
258 ## Displays the user directory with customization status and customization form for when it is being customized.
259 ##
260 #macro (displayUserDirectoryCustomizationOptions $customize)
261 ##
262 ## Ability to customize the view.
263 ##
264 #if ($customize)
265 #displayUserDirectoryCustomizationForm()
266 #elseif ($isCustomized)
267 {{warning}}
268 $services.localization.render('xe.userdirectory.isCustomizedWarning', [
269 "$doc.fullName",
270 $escapetool.url({
271 'customize': true,
272 'action': 'reset',
273 'xredirect': $xredirect,
274 'form_token': $services.csrf.token
275 }),
276 "$doc.fullName",
277 'customize=true'
278 ])
279 {{/warning}}
280 #elseif ($isGuest)
281 {{info}}
282 $services.localization.render('xe.userdirectory.canCustomizeInfoGuest', ["path:$doc.getURL('login')"])
283 {{/info}}
284 #else
285 {{info}}
286 $services.localization.render('xe.userdirectory.canCustomizeInfo', ["$doc.fullName", 'customize=true'])
287 {{/info}}
288 #end
289 #end
290
291 ##
292 ## Displays the user directory.
293 ##
294 #macro (displayUserDirectory $customize)
295 #set ($discard = $xwiki.jsx.use('XWiki.UserDirectoryMacros'))
296 #displayUserDirectoryCustomizationOptions($customize)
297
298 #if ($customize)
299 (% id="HUserDirectoryCustomizePreview" %)
300 == {{translation key="xe.userdirectory.customizePreviewTitle"/}} ==
301
302 #end
303 #displayUserDirectoryLiveTable()
304 #end
305 {{/velocity}}