Wiki source code of XWiki.Configurable
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | {{velocity}} | ||
| 2 | #* | ||
| 3 | * This part takes the configuration from any documents containing XWiki.Configurable objects and creates a form | ||
| 4 | * for each. To includeForm this document, you may specify: | ||
| 5 | * | ||
| 6 | * $section - String - The section which we are administrating eg: "Registration", "Users", or "Import". | ||
| 7 | * If none is specified then it checks for a request parameter called "section" and uses that, | ||
| 8 | * if no parameter, then this code assumes that it is part of the admin icons sheet and adds icons | ||
| 9 | * for any section which is not in $sections, in that event, this code assumes it is being run | ||
| 10 | * inside of a <ul> block. | ||
| 11 | * | ||
| 12 | * $sections - List<String> - If section is not specified, any sections on this list will not have icons made for them | ||
| 13 | * the assumption being that the icons are already there. If section is specified then this | ||
| 14 | * is not taken into account and may safely be undefined. | ||
| 15 | * | ||
| 16 | * $currentDoc - String (document.fullName) - The administration document, users who don't have permission to edit | ||
| 17 | * it will not be able to include applications (possibly injecting | ||
| 18 | * arbitrary code.) if none specified then $doc.getFullName() is used. | ||
| 19 | * | ||
| 20 | * $globaladmin - boolean - If set true then we will assume we are administrationg the entire wiki. | ||
| 21 | * If not set then we look for a request parameter called "editor" if that exists and equals | ||
| 22 | * "globaladmin" then $globaladmin is true, if it doesn't exist then we check to see if | ||
| 23 | * $currentDoc.getFullName() equals "XWiki.XWikiPreferences". | ||
| 24 | * | ||
| 25 | * $doNotUnlockConfigurableDocuments - boolean - If true then this code will not make any attempt to unlock configurable | ||
| 26 | * documents. By default it does because it locks any document in the | ||
| 27 | * section which is being configured which would lead to a lot of stray | ||
| 28 | * locks if they weren't all cancelled. Only recommended if this page is | ||
| 29 | * being included twice in the same page. | ||
| 30 | *### | ||
| 31 | ## Constants: | ||
| 32 | #set($redirectParameter = 'xredirect') | ||
| 33 | #set($nameOfThisDocument = 'XWiki.Configurable') | ||
| 34 | ## | ||
| 35 | ## Form submission depends on this. | ||
| 36 | $xwiki.jsfx.use('js/xwiki/actionbuttons/actionButtons.js', true) | ||
| 37 | ## | ||
| 38 | #if(!$section) | ||
| 39 | #set($section = $request.getParameter('section')) | ||
| 40 | #end | ||
| 41 | #if(!$currentDoc) | ||
| 42 | #set($currentDoc = $doc.getFullName()) | ||
| 43 | #end | ||
| 44 | ## Get value of $globaladmin if not specified. | ||
| 45 | #if("$!globaladmin" == '') | ||
| 46 | #if($editor != 'globaladmin' | ||
| 47 | && $request.getParameter('editor') != 'globaladmin' | ||
| 48 | && $currentDoc != "XWiki.XWikiPreferences") | ||
| 49 | ## | ||
| 50 | #set($globaladmin = false) | ||
| 51 | #else | ||
| 52 | #set($globaladmin = true) | ||
| 53 | #end | ||
| 54 | #end | ||
| 55 | #set($currentSpace = $xwiki.getDocument("$currentDoc").getSpace()) | ||
| 56 | ## | ||
| 57 | ## This application should not run with programming rights because it evaluates code which may not be trustworthy. | ||
| 58 | ## Removing the next line will open a security hole. | ||
| 59 | #sandboxDocument($nameOfThisDocument) | ||
| 60 | ## | ||
| 61 | ## This application locks every document in a section while that section is being edited so we should | ||
| 62 | ## check for locks held by the current user on any of the applications configured here and remove them. | ||
| 63 | #if(!$doNotUnlockConfigurableDocuments) | ||
| 64 | #set($outputList = []) | ||
| 65 | #findNamesOfAppsToConfigure("", $globaladmin, $currentSpace, $outputList) | ||
| 66 | ## We don't want to generate javascript which unlocks the current document just after we got finished locking it. | ||
| 67 | #set($discard = $outputList.remove($currentDoc)) | ||
| 68 | #unlockDocuments($outputList) | ||
| 69 | #end | ||
| 70 | ## | ||
| 71 | ##------------------------------------------------------------------------------------------------------------ | ||
| 72 | ## If $section exists then we are viewing the admin page for a perticular section. | ||
| 73 | ## eg: 'Registration', 'Presentation', 'Import' etc. | ||
| 74 | ##------------------------------------------------------------------------------------------------------------ | ||
| 75 | ## | ||
| 76 | #if($section && $section != '') | ||
| 77 | ## | ||
| 78 | ## Searches the database for names of apps to be configured | ||
| 79 | #set($outputList = []) | ||
| 80 | #findNamesOfAppsToConfigure($section, $globaladmin, $xwiki.getDocument("$currentDoc").getSpace(), $outputList) | ||
| 81 | ## | ||
| 82 | #foreach($appName in $outputList) | ||
| 83 | ## | ||
| 84 | = $msg.get("admin.customize") __[[$appName>>$appName]]__: = | ||
| 85 | ## | ||
| 86 | ## Make sure the current user has permission to edit the configurable application. | ||
| 87 | #if(!$xcontext.hasAccessLevel('edit', $appName)) | ||
| 88 | {{error}}$msg.get('xe.admin.configurable.noPermissionThisApplication'){{/error}} | ||
| 89 | #else | ||
| 90 | ## | ||
| 91 | ## Get the configurable application | ||
| 92 | #set($app = $xwiki.getDocument($appName)) | ||
| 93 | ## | ||
| 94 | ## If the document was not last saved by a user with edit privilage on this page | ||
| 95 | ## then we can't safely display the page but we should warn the viewer. | ||
| 96 | #set($hasAccess = false) | ||
| 97 | #checkDocumentSavedByAuthorizedUser($app, $currentDoc, $hasAccess) | ||
| 98 | #if(!$hasAccess) | ||
| 99 | {{error}}$msg.get('xe.admin.configurable.applicationAuthorNoAdmin', [$app.Author]){{/error}} | ||
| 100 | #else | ||
| 101 | ## | ||
| 102 | ## Locking document | ||
| 103 | ##------------------------------------------------------------------------------------------------------------ | ||
| 104 | #if($app.getLocked()) | ||
| 105 | #set($locked = true) | ||
| 106 | #end | ||
| 107 | ## If the document is locked and not by the current user and forceEdit is not set true, | ||
| 108 | #if($locked && $app.getLockingUser() != $xcontext.getUser() && !$request.getParameter('forceEdit')) | ||
| 109 | #set($requestURL = "$request.getRequestURL()") | ||
| 110 | #if($requestURL.indexOf("?") == -1) | ||
| 111 | #set($requestURL = "${requestURL}?") | ||
| 112 | #end | ||
| 113 | {{error}}$msg.get("doclockedby") $app.getLockingUser() [[$msg.get("forcelock")>>${requestURL}&forceEdit=1]]{{/error}} | ||
| 114 | #else | ||
| 115 | ## If the document is not already locked, attempt to aquire the lock. | ||
| 116 | #if(!$locked) | ||
| 117 | ## Try to use an ajax call to lock the document. | ||
| 118 | {{html clean=false wiki=true}} | ||
| 119 | </p><noscript> | ||
| 120 | {{warning}}$msg.get('xe.admin.configurable.cannotLockNoJavascript'){{/warning}} | ||
| 121 | </noscript> | ||
| 122 | <script type="text/javascript"> | ||
| 123 | document.observe("dom:loaded", function() { | ||
| 124 | new Ajax.Request("$xwiki.getURL($app.getFullName(), 'lock', 'ajax=1')"); | ||
| 125 | }); | ||
| 126 | </script><p> | ||
| 127 | {{/html}} | ||
| 128 | #set($discard = $lockedDocumentNames.add($app.getFullName())) | ||
| 129 | #end | ||
| 130 | ##------------------------------------------------------------------------------------------------------------ | ||
| 131 | ## Done Locking. | ||
| 132 | ## | ||
| 133 | ## Get all objects of the "Configurable" class from this document. | ||
| 134 | #set($allConfigurableObjs = $app.getObjects('XWiki.Configurable')) | ||
| 135 | ## Seperate out the objects which are for this section. | ||
| 136 | #set($configurableObjs = []) | ||
| 137 | #foreach($configurableObj in $allConfigurableObjs) | ||
| 138 | #if($app.getValue('displayInSection', $configurableObj) == $section) | ||
| 139 | ## If this is space admin, then don't display global, if global don't display space. | ||
| 140 | #if($globaladmin == ($app.getValue('configureGlobally', $configurableObj) == 1)) | ||
| 141 | #set($discard = $configurableObjs.add($configurableObj)) | ||
| 142 | #end | ||
| 143 | #end | ||
| 144 | #end | ||
| 145 | #if($configurableObjs.size() == 0) | ||
| 146 | ## Internal error, not translated. | ||
| 147 | {{error}}Internal error: All objects were filtered out for application: $appName.{{/error}} | ||
| 148 | #else | ||
| 149 | #set($formAction = "$xwiki.getURL($app.getFullName(), 'save')") | ||
| 150 | #set($formId = "$section.toLowerCase()_$app.getFullName()") | ||
| 151 | #set($escapedAppName = $escapetool.html($app.getFullName())) | ||
| 152 | {{html clean=false wiki=false}} | ||
| 153 | #foreach($configurableObj in $configurableObjs) | ||
| 154 | ## Display the header if one exists. | ||
| 155 | #set($heading = $app.getValue('heading', $configurableObj)) | ||
| 156 | #if($heading && $heading != '') | ||
| 157 | {{/html}} | ||
| 158 | == #evaluate($heading) == | ||
| 159 | {{html clean=false wiki=false}} | ||
| 160 | #end | ||
| 161 | ## If the class specifies custom code to evaluate, | ||
| 162 | ## then close the html macro, evaluate it and reopen the macro. | ||
| 163 | #set($codeToExecute = "$!app.getValue('codeToExecute', $configurableObj)") | ||
| 164 | #if($codeToExecute != '') | ||
| 165 | {{/html}} | ||
| 166 | #evaluate($codeToExecute) | ||
| 167 | {{html clean=false wiki=false}} | ||
| 168 | #end | ||
| 169 | ## | ||
| 170 | ## If propertiesToShow is set, then we will only show the properties contained therein. | ||
| 171 | #set($propertiesToShow = $app.getValue('propertiesToShow', $configurableObj)) | ||
| 172 | #if(!$propertiesToShow || $propertiesToShow.getClass().getName().indexOf('List') == -1) | ||
| 173 | #set($propertiesToShow = []) | ||
| 174 | #end | ||
| 175 | ## | ||
| 176 | ## If linkPrefix is set, then we will make each property label a link which starts with that prefix. | ||
| 177 | #set($linkPrefix = "$!app.getValue('linkPrefix', $configurableObj)") | ||
| 178 | ## | ||
| 179 | ## If the Configurable object specifies a configuration class, use it, | ||
| 180 | ## otherwise assume custom forms are used instead. | ||
| 181 | #set($configClassName = "$!app.getValue('configurationClass', $configurableObj)") | ||
| 182 | #if($configClassName != '') | ||
| 183 | #set($objClass = $xwiki.getDocument("$configClassName").getxWikiClass()) | ||
| 184 | #if(!$objClass || $objClass.getClass().getName().indexOf('.Class') == -1) | ||
| 185 | {{/html}} | ||
| 186 | {{error}}$msg.get('xe.admin.configurable.configurationClassNonexistant'){{/error}} | ||
| 187 | {{html clean=false wiki=false}} | ||
| 188 | #else | ||
| 189 | ## Use the first object from the document which is of the configuration class. | ||
| 190 | #set($obj = $app.getObject($objClass.getName())) | ||
| 191 | ## | ||
| 192 | #if(!$obj || $obj.getClass().getName().indexOf('.Object') == -1) | ||
| 193 | {{/html}} | ||
| 194 | {{error}} | ||
| 195 | $msg.get('xe.admin.configurable.noObjectOfConfigurationClassFound', | ||
| 196 | [$objClass.getName(), $app.getFullName()]) | ||
| 197 | {{/error}} | ||
| 198 | {{html clean=false wiki=false}} | ||
| 199 | #else | ||
| 200 | #define($formHtml) | ||
| 201 | ## We don't begin the form until we have content for it so that a configurable can specify a | ||
| 202 | ## custom form in codeToExecute and if that configurable object is the first of it's kind in that | ||
| 203 | ## document, the custom form will not be put inside of our form. | ||
| 204 | #if(!$insideForm) | ||
| 205 | <form id="$formId" method="post" action="$formAction" onsubmit="cancelCancelEdit()"> | ||
| 206 | <fieldset> | ||
| 207 | #set($insideForm = true) | ||
| 208 | #end | ||
| 209 | #foreach($propName in $objClass.getPropertyNames()) | ||
| 210 | #if($propertiesToShow.size() > 0 && !$propertiesToShow.contains($propName)) | ||
| 211 | ## Silently skip over this property. | ||
| 212 | #else | ||
| 213 | <p> | ||
| 214 | #set($prettyName = "#evaluate($app.displayPrettyName($propName, $obj))") | ||
| 215 | ## App Name is prepended to for= to make label work with id which is modified to prevent collisions. | ||
| 216 | <label for="${escapedAppName}_$objClass.getName()_0_$propName"> | ||
| 217 | #if($linkPrefix != '') | ||
| 218 | #set($linkScript = "$linkPrefix$propName") | ||
| 219 | <a href="$escapetool.html("#evaluate($linkScript)")">$escapetool.html($prettyName)</a> | ||
| 220 | #else | ||
| 221 | $escapetool.html($prettyName) | ||
| 222 | #end | ||
| 223 | </label> | ||
| 224 | $obj.display($propName, "edit") | ||
| 225 | </p> | ||
| 226 | #end## If property is in propertiesToShow | ||
| 227 | #end## Foreach property in this class | ||
| 228 | #end## define $formHtml | ||
| 229 | ## Strip pre tags and html macro invocations which $obj.display inserts. | ||
| 230 | ## then prepend application name to ids to prevent id collissions. | ||
| 231 | $formHtml.toString().replaceAll('\{\{[/]?html[^}]*\}\}|<[/]?pre>', '').replaceAll(" id='", " id='${escapedAppName}_") | ||
| 232 | #end## If object exists | ||
| 233 | #end## If class exists | ||
| 234 | #end## If class name is specified. | ||
| 235 | #end## Foreach configurable object found in this document | ||
| 236 | ## If a form was started then we end it. | ||
| 237 | #if($insideForm) | ||
| 238 | ## We add in a redirect field to prevent the user from being carried away when they save | ||
| 239 | ## if they don't have javascript. | ||
| 240 | #set($thisURL = $request.getRequestURL()) | ||
| 241 | #if($request.getQueryString() && $request.getQueryString().length() > 0) | ||
| 242 | #set($thisURL = "${thisURL}?$request.getQueryString()") | ||
| 243 | #end | ||
| 244 | <input type="hidden" id="${escapedAppName}_redirect" name="$redirectParameter" value="$escapetool.html($thisURL)" /> | ||
| 245 | </fieldset> | ||
| 246 | <div class="bottombuttons"> | ||
| 247 | <p class="admin-buttons"> | ||
| 248 | <span class="buttonwrapper"> | ||
| 249 | ## Text to display on the button | ||
| 250 | #set($buttonText = "$msg.get('admin.save') $escapedAppName") | ||
| 251 | <input class="button" type="submit" name="action_saveandcontinue" value="$buttonText" /> | ||
| 252 | </span> | ||
| 253 | </p> | ||
| 254 | </div> ## bottombuttons | ||
| 255 | </form> | ||
| 256 | #set($insideForm = false) | ||
| 257 | #end | ||
| 258 | {{/html}} | ||
| 259 | #end## If there are configurable objects | ||
| 260 | #end## If document is not locked or forceEdit is enabled | ||
| 261 | #end## If app author has permission to edit admin page | ||
| 262 | #end## If the current user has permission to edit the configurable application. | ||
| 263 | #end## Foreach document name in names to configure | ||
| 264 | {{html clean=false wiki=false}} | ||
| 265 | <script type="text/javascript"> | ||
| 266 | /* <![CDATA[ */ | ||
| 267 | ## Alt+Shift+S presses the first saveAndContinue button it finds, not what we want so we will disable edit shortcuts. | ||
| 268 | XWiki.actionButtons.EditActions = Object.extend(XWiki.actionButtons.EditActions, {addShortcuts : function() { }}); | ||
| 269 | ## | ||
| 270 | ## TODO: cancel and "submit all" buttons. | ||
| 271 | //]]> | ||
| 272 | </script> | ||
| 273 | {{/html}} | ||
| 274 | ## | ||
| 275 | ## | ||
| 276 | #else | ||
| 277 | ## | ||
| 278 | ##------------------------------------------------------------------------------------------------------------ | ||
| 279 | ## If section is not set then we are viewing the main administration page. | ||
| 280 | ##------------------------------------------------------------------------------------------------------------ | ||
| 281 | ## | ||
| 282 | ## If there is no list called sections then we set sections to an empty list. | ||
| 283 | #if(!$sections || $sections.getClass().getName().indexOf("List") == -1) | ||
| 284 | #set($sections = []) | ||
| 285 | #end | ||
| 286 | ## | ||
| 287 | ## We have to create a list of documents which the current user doesn't have permission to view. | ||
| 288 | ## So we can add an error messsage to the bottom of the page if there are any. | ||
| 289 | #set($appsUserCannotView = []) | ||
| 290 | ## | ||
| 291 | ## A list of sections (to be added) which the user is not allowed to edit, icons will be displayed with a message | ||
| 292 | #set($sectionsUserCannotEdit = []) | ||
| 293 | ## List of sections to be added, in order by creationDate of oldest contained application. | ||
| 294 | #set($sectionsToAdd = []) | ||
| 295 | ## Map of URL of icon to use by the name of the section to use that icon on. | ||
| 296 | #set($iconBySection = {}) | ||
| 297 | ## | ||
| 298 | #set($outputList = []) | ||
| 299 | #findNamesOfAppsToConfigure("", $globaladmin, $currentSpace, $outputList) | ||
| 300 | ## | ||
| 301 | #foreach($appName in $outputList) | ||
| 302 | ## | ||
| 303 | ## Get the configurable application | ||
| 304 | #set($app = $xwiki.getDocument($appName)) | ||
| 305 | ## | ||
| 306 | ## If getDocument returns null, then warn the user that they don't have view access to that application. | ||
| 307 | #if(!$app) | ||
| 308 | #set($discard = $appsUserCannotView.add($appName)) | ||
| 309 | #end | ||
| 310 | ## | ||
| 311 | #set($configurableObjects = $app.getObjects('XWiki.Configurable')) | ||
| 312 | #foreach($configurableObject in $configurableObjects) | ||
| 313 | #set($displayInSection = $app.getValue('displayInSection', $configurableObject)) | ||
| 314 | ## | ||
| 315 | ## If there is no section for this configurable or if the section cannot be edited, then check if the | ||
| 316 | ## application can be edited by the current user, if so then we display the icon from the current app and | ||
| 317 | ## don't display any message to tell the user they can't edit that section. | ||
| 318 | #if(!$sections.contains($displayInSection) || $sectionsUserCannotEdit.contains($displayInSection)) | ||
| 319 | ## | ||
| 320 | ## If there is no section for this configurable, then we will have to add one. | ||
| 321 | #if(!$sections.contains($displayInSection) && !$sectionsToAdd.contains($displayInSection)) | ||
| 322 | #set($discard = $sectionsToAdd.add($displayInSection)) | ||
| 323 | #end | ||
| 324 | ## | ||
| 325 | ## If an attachment by the filename iconAttachment exists and is an image | ||
| 326 | #set($attachment = $app.getAttachment("$app.getValue('iconAttachment', $configurableObject)")) | ||
| 327 | #if($attachment && $attachment.isImage()) | ||
| 328 | ## Set the icon for this section as the attachment URL. | ||
| 329 | #set($discard = $iconBySection.put($displayInSection, $app.getAttachmentURL($attachment.getFilename()))) | ||
| 330 | #end | ||
| 331 | ## | ||
| 332 | ## If the user doesn't have edit access to the application, we want to should show a message on the icon | ||
| 333 | #if(!$xcontext.hasAccessLevel("edit", $app.getFullName())) | ||
| 334 | #if(!$sectionsUserCannotEdit.contains($displayInSection)) | ||
| 335 | #set($discard = $sectionsUserCannotEdit.add($displayInSection)) | ||
| 336 | #end | ||
| 337 | #elseif($sectionsUserCannotEdit.contains($displayInSection)) | ||
| 338 | ## If the user didn't have access to the section before but does have access to _this_ app which is | ||
| 339 | ## configured in the section, then the section becomes accessable. | ||
| 340 | #set($discard = $sectionsUserCannotEdit.remove($displayInSection)) | ||
| 341 | #end | ||
| 342 | #end## If section doesn't exist or user doesn't have access. | ||
| 343 | #end## Foreach configurable object in this app. | ||
| 344 | #end## Foreach application which is configurable. | ||
| 345 | ## | ||
| 346 | ## Now we go through sectionsToAdd and generate icons for them | ||
| 347 | #set($defaultIcon = $xwiki.getAttachmentURL('XWiki.Configurable', 'DefaultAdminSectionIcon.png')) | ||
| 348 | #if($globaladmin) | ||
| 349 | #set($queryString = "editor=globaladmin&section=") | ||
| 350 | #else | ||
| 351 | #set($queryString = "space=${currentSpace}&section=") | ||
| 352 | #if($request.getParameter('editor')) | ||
| 353 | #set($queryString = "editor=$escapetool.url($request.getParameter('editor'))&$queryString") | ||
| 354 | #end | ||
| 355 | #end | ||
| 356 | {{html clean=false wiki=false}} | ||
| 357 | #foreach($sectionToAdd in $sectionsToAdd) | ||
| 358 | #set($icon = $iconBySection.get($sectionToAdd)) | ||
| 359 | #if(!$icon) | ||
| 360 | #set($icon = $defaultIcon) | ||
| 361 | #end | ||
| 362 | <li class="$escapetool.html($sectionToAdd).replaceAll(' ', '_')"> | ||
| 363 | #set($hasAccess = !$sectionsUserCannotEdit.contains($sectionToAdd)) | ||
| 364 | #if($hasAccess) | ||
| 365 | <a href="$xwiki.getURL($currentDoc, $xcontext.getAction(), "$queryString$escapetool.url($sectionToAdd)")"> | ||
| 366 | #else | ||
| 367 | <a title="$msg.get('xe.admin.configurable.sectionIconNoAccessTooltip')"> | ||
| 368 | #end | ||
| 369 | <img src="$icon" alt="$escapetool.html($sectionToAdd) icon"/> | ||
| 370 | $escapetool.html($sectionToAdd) | ||
| 371 | #if(!$hasAccess) | ||
| 372 | <br/><span class="errormessage">$msg.get('xe.admin.configurable.sectionIconNoAccess')</span> | ||
| 373 | #end | ||
| 374 | </a> | ||
| 375 | </li> | ||
| 376 | #end | ||
| 377 | {{/html}} | ||
| 378 | ## | ||
| 379 | ## Finally we display an error message if there are any applications which we were unable to view. | ||
| 380 | #if($appsUserCannotView.size() > 0) | ||
| 381 | {{error}}$msg.get('xe.admin.configurable.noViewAccessSomeApplications', [$appsUserCannotView]){{/error}} | ||
| 382 | #end | ||
| 383 | #end## If we should be looking at the main administration page. | ||
| 384 | ## | ||
| 385 | ##------------------------------------------------------------------------------------------------------------ | ||
| 386 | ## The Macros, nothing below this point is run directly. | ||
| 387 | ##------------------------------------------------------------------------------------------------------------ | ||
| 388 | ## | ||
| 389 | #* | ||
| 390 | * | ||
| 391 | * Any documents which are on the provided list ($documentNames) which are locked by the current user will be unlocked. | ||
| 392 | * If this macro has programming rights, then they are unlocked programmatically, otherwise a javascript tag is | ||
| 393 | * generated with ajax calls to cancel for all of the documents. If there are documents on this list which are not | ||
| 394 | * locked by the current user, then they are ignored. | ||
| 395 | * | ||
| 396 | * @param $documentNames - List<String> - fullNames of documents which should be unlocked if they are locked by the | ||
| 397 | * current user. | ||
| 398 | *### | ||
| 399 | #macro(unlockDocuments $documentNames) | ||
| 400 | #if($documentNames.size() > 0) | ||
| 401 | #set($sql = "doc.fullName=") | ||
| 402 | #foreach($documentName in $documentNames) | ||
| 403 | #set($sql = "${sql}'$documentName' or doc.fullName=") | ||
| 404 | #end | ||
| 405 | ## Trim the dangling ' or doc.fullName=?' | ||
| 406 | #set($sql = $sql.substring(0, $sql.lastIndexOf(' or doc.fullName='))) | ||
| 407 | #set($sql = ", XWikiLock lock where lock.docId=doc.id and lock.userName='$xcontext.getUser()' and (${sql})") | ||
| 408 | #set($namesOfdocumentsToUnlock = $xwiki.searchDocuments($sql)) | ||
| 409 | ## Use ajax and hope the user runs javascript. | ||
| 410 | {{html clean=false wiki=false}} | ||
| 411 | <script type="text/javascript"> | ||
| 412 | document.observe("dom:loaded", function() { | ||
| 413 | #foreach($nameOflockedDocument in $namesOfdocumentsToUnlock) | ||
| 414 | new Ajax.Request("$xwiki.getURL($nameOflockedDocument, 'cancel', 'ajax=1')"); | ||
| 415 | #end | ||
| 416 | }); | ||
| 417 | </script> | ||
| 418 | {{/html}} | ||
| 419 | #end## If output list size > 0 | ||
| 420 | #end## Macro | ||
| 421 | ## | ||
| 422 | #* | ||
| 423 | * Find names of documents which contain objects of the class 'XWiki.Configurable' | ||
| 424 | * | ||
| 425 | * @param $section - String - Look for apps which specify that they should be configured in this section, | ||
| 426 | * if null or "" then returns them for all sections. | ||
| 427 | * | ||
| 428 | * @param $globaladmin - boolean - If true then we will look for applications which should be configured globally. | ||
| 429 | * | ||
| 430 | * @param $space - String - If not looking for apps which are configured globally, then this is the space where we | ||
| 431 | * will look for apps in. If null or "" or if $globaladmin is true, then all spaces will be | ||
| 432 | * searched. | ||
| 433 | * | ||
| 434 | * @param $outputList - List - The returns from this macro will be put in this list, passing the list as a parameter | ||
| 435 | * a safety measure because macros can't return values. | ||
| 436 | *### | ||
| 437 | #macro(findNamesOfAppsToConfigure, $section, $globaladmin, $space, $outputList) | ||
| 438 | ## Use a parameterized sql query to prevent injection. | ||
| 439 | #set($params = []) | ||
| 440 | #if($section && $section != '') | ||
| 441 | #set($discard = $params.add("$section")) | ||
| 442 | #set($sqlA = ' StringProperty as section,') | ||
| 443 | #set($sqlB = " and section.id=obj.id and section.name='displayInSection' and section.value=?") | ||
| 444 | #else | ||
| 445 | ## Make sure they are "" in case they were set prior to calling the macro. | ||
| 446 | #set($sqlA = '') | ||
| 447 | #set($sqlB = '') | ||
| 448 | #end | ||
| 449 | ## Set up query based on value of $globaladmin | ||
| 450 | #if($globaladmin == true) | ||
| 451 | #set($sqlC = '1') | ||
| 452 | #else | ||
| 453 | #if($space && $space != '') | ||
| 454 | #set($sqlC = '0 and doc.space = ?') | ||
| 455 | #set($discard = $params.add($space)) | ||
| 456 | #else | ||
| 457 | #set($sqlC = '0') | ||
| 458 | #end | ||
| 459 | #end | ||
| 460 | #set($sql = ", BaseObject as obj,$sqlA IntegerProperty as global where " | ||
| 461 | + "doc.fullName=obj.name and obj.className='XWiki.Configurable'$sqlB " | ||
| 462 | + "and global.id=obj.id and global.name='configureGlobally' and global.value=$sqlC " | ||
| 463 | + "order by doc.creationDate") | ||
| 464 | ## | ||
| 465 | ## Run the search | ||
| 466 | #set($outputList = $xwiki.searchDocuments($sql, 0, 0, $params)) | ||
| 467 | ## | ||
| 468 | #end | ||
| 469 | ## | ||
| 470 | #* | ||
| 471 | * If this document is saved with programming access or is includeForm'd into a document with programming, we have to | ||
| 472 | * drop programming rights in order for it to run safely because it evaluates potentially untrustworthy code. | ||
| 473 | *### | ||
| 474 | #macro(sandboxDocument) | ||
| 475 | #if($xcontext.hasProgrammingRights()) | ||
| 476 | $xcontext.getContext().getDoc().setContentAuthor('XWiki.XWikiGuest') | ||
| 477 | #end | ||
| 478 | #end | ||
| 479 | ## | ||
| 480 | #* | ||
| 481 | * Try to determine whether a document was edited by a user who has edit right on this page. This is trickey because | ||
| 482 | * documents are imported with the name XWiki.XWikiGuest who has no access to anything after import. | ||
| 483 | * | ||
| 484 | * @param theDoc - Document who's editor should be checked for edit access on this document. | ||
| 485 | *# | ||
| 486 | #macro(checkDocumentSavedByAuthorizedUser, $docToCheck, $currentDoc, $hasAccess) | ||
| 487 | ## The system is started and the only user is XWikiGuest who has admin right but gives it up when he imports the default | ||
| 488 | ## documents, we are checking to see if this looks like the guest imported the document with the first import. | ||
| 489 | #if($docToCheck.getWiki() == $xcontext.getMainWikiName() | ||
| 490 | && $docToCheck.getVersion() == '1.1' | ||
| 491 | && $docToCheck.getCreator() != $docToCheck.getContentAuthor() | ||
| 492 | && $docToCheck.getContentAuthor() == 'XWiki.XWikiGuest') | ||
| 493 | ## | ||
| 494 | #set($userToCheck = $docToCheck.getCreator()) | ||
| 495 | #else | ||
| 496 | #set($userToCheck = $docToCheck.getAuthor()) | ||
| 497 | #end | ||
| 498 | #set($hasAccess = $xwiki.hasAccessLevel("edit", $userToCheck, $currentDoc)) | ||
| 499 | #end | ||
| 500 | {{/velocity}} |