Replace page authors from another subwiki

Last modified by Clemens Robbenhaar on 2025/02/12 12:25

cogChange references of users from another subwiki to local user references, fixing (or introducing) possible access right problems
Type
CategoryOther
Developed by

Clemens Robbenhaar

Rating
0 Votes
LicenseBSD license

Description

This snippet looks for users which are referenced as creator, author or content author from some subwiki in other subwikis, displaying them and optionally replacing them by references to local users,

Especially after copying a wiki as template the users local to the template wiki will keep the authorship of the pages in the copied wiki. If the local users had scripting or admin rights on the template wiki, they will not have them in the copy - instead their local copies have them. This snippet is intended to fix this situation.
Also after deleting a subwiki, any references of their users will be missing, which sometimes causes error messages while creating new subwikis of accessing a page which references the users from that deleted subwiki.

Replacing the user references to that subwiki is considered a "best effort" - it is not checked if the users actually exist in the local wiki. If you prefer to assign authorship to another user, feel free to adapt the relevant places in the script. (Before doing it better check of it is safe to do so and you are not giving scripts on pages programming rights when these contain unsafe content. See the permission types documentation.

{{velocity}}
## here give the name of the sub wiki
#set($name = "somesubwiki")

#set($wikis = $services.wiki.getAllIds())
## or define them explicitly if you know the ids
##set($wikis = ['subwiki1', 'subwiki3'])
#set($thisWiki = $services.wiki.getCurrentWikiId())
#set($xwikiContext = $xcontext.context)
#set($namec = "${name}:")
#set($nameclen = $namec.length())
#set($update = "$!request.getParameter('update')")
#set($count = 0)
#foreach($wikiId in $wikis)
#if ($wikiId != $name)

== check $wikiId ==

  #set($discard = $xwikiContext.setWikiId($wikiId))
  #set($queryStr = "select doc.fullName from Document doc where doc.creator like :name or doc.author like :name or doc.contentAuthor like :name")
  #set($query = $services.query.xwql($queryStr))
  #set($query = $query.bindValue('name').literal($namec).anyChars().query())
  #set($results = $query.execute())
  Results: $results.size()
  #set($count = $mathtool.add($count, $results.size()))
  #set($documentsToUpdate =[])
  #foreach ($result in $results)
    #set($resDoc = $xwiki.getDocument($result))
    #if($resDoc)
      #if($update != '')
        #set($discard = $documentsToUpdate.add($resDoc))
      #else
  * $result with
  ** creator $resDoc.creator
  ** author $resDoc.author
  ** content author $resDoc.contentAuthor
      #end
    #else
  * $result (inaccessible)
    #end
  #end
  #foreach ($document in $documentsToUpdate)
    #set($updated = false)
    #set ($internalDocument = $document.getDocument())
    #set ($creator = $document.creator)
    #if ($creator.startsWith($namec))
      #set ($creator = $creator.substring($nameclen, $creator.length()))
      ** $document change creator $document.creator to $creator
      #set($discard = $internalDocument.setCreator('XWiki.superadmin'))
      #set($updated = true)
    #end
    #set ($author = $document.author)
    #if ($author.startsWith($namec))
      #set ($author = $author.substring($nameclen, $author.length()))
      ** $document change author $document.author to $author
      #set($discard = $internalDocument.setAuthor($author))
      #set($updated = true)
    #end
    #set ($contentAuthor = $document.contentAuthor)
    #if ($contentAuthor.startsWith($namec))
      #set ($contentAuthor = $contentAuthor.substring($nameclen, $contentAuthor.length()))
      ** $document change content author $document.contentAuthor to $contentAuthor
      #set($discard = $internalDocument.setContentAuthor($contentAuthor))
      #set($updated = true)
    #end
    #if ($updated)
      #set ($discard = $internalDocument.setMetaDataDirty(false))
      #set ($discard = $internalDocument.setContentDirty(false))
      #set ($store = $xwiki.getXWiki().getHibernateStore())
      #set ($discard = $store.saveXWikiDoc($internalDocument, $xcontext.context))
      * updated $document
    #end
  #end
#end
#end
#set($discard = $xwikiContext.setWikiId($thisWiki))

#if ($update != '')
{{html wiki="false"}}
<span class="buttonwrapper"><a class="btn secondary" href="$escapetool.xml($doc.getURL())">Check again</a></span>
{{/html}}
#elseif ($count > 0)
{{html wiki="false"}}
<span class="buttonwrapper"><a class="btn primary" href="$escapetool.xml($doc.getURL('view','update=1'))">Update</a></span>
{{/html}}
#end
{{/velocity}}

Prerequisites & Installation Instructions

After copying the code to a page, make sure that you change the name of the subwiki at the second line in the script: #set($name = "somesubwiki").

It might be necessary to reindex the affected subwikis after running an actual update, as the changes are made without creating a new version to the modified wiki pages, and thus not triggering an update to the search index.

Get Connected