Help for query: all docs not hidden and current user has view access

I want to make a “random page”. I thought to request all articles real users created a query for all docs that are not hidden and where the current user has view rights would be a nice approach.

This I have so far.

## omit space XWiki as I don't want user profiles in there
#set ($xwql = "where doc.hidden = false AND doc.space NOT LIKE 'XWiki'")
#set ($allItems = $services.query.xwql($xwql).execute())

## some code here to get a valid random number and then display
...
{{display reference="$allItems[$randomnumber]" /}}

I do have some code iterating $allItems and check whether current user has view access and build a new array to use.

#set($allItemsAccess = [])
#foreach ($item in $allItems)
  #if($xwiki.hasAccessLevel('view', $xcontext.user, $item))
    ## use $opferVariable to not have printed out 'true'
    #set($opferVariable = $allItemsAccess.add($item))
  #end
#end

But it would be much nicer if the first query wouldn’t request all articles current user has no acces to. Can you give me a hint?

Regards, Simpel

BTW: The size of $allItemsAccess is very varying from request to request. Hitting F5 and the size is different but nothing has changed in the wiki.

PPS: If you have another idea for a good approach of a random page tell me.

There’s currently no way in XWiki to query computed permissions from the DB.

1 Like

My current random page now looks like this:

{{velocity}}
  ## omit space XWiki as I don't want user profiles in there
  #set ($xwql = "where doc.hidden = false AND doc.space NOT LIKE 'XWiki'")
  ## array of all pages
  #set ($allItems = $services.query.xwql($xwql).execute())
  ## count the pages
  #set ($count = $allItems.size())
{{/velocity}}

{{groovy}}
  // Because velocitys mathtool isn't working create random number with groovy and use $count as max. value
  // velocity "$count" is groovy "count"
  randomnumber = Math.abs(new Random().nextInt() % count)
  // following line prevents print out of randomnumber
  assert randomnumber instanceof Integer
{{/groovy}}

{{velocity}}
  ## groovy "randomnumber" is velocity "$randomnumber"
  ## Velocity random: $randomnumber

  #set($randomPage = $allItems[$randomnumber])
  ## redirect to random page or reload if not accessible by user
  #if($xwiki.hasAccessLevel('view', $randomPage))
    #set($randomPage = $xwiki.getURL($randomPage))
    $response.sendRedirect($randomPage)
  #else
    ## refresh this page to create a new random number
    #set($thisPage = $xwiki.getURL($doc))
    $response.sendRedirect($thisPage)
  #end
{{/velocity}}

Simpel

Hi @Simpel . I don’t understand your comment. What’s not working with Velocity mathtool?

I’ve tested it with the following and it works fine for me:

{{velocity}}
#set ($count = 1000)
$mathtool.random(0, $count)
{{/velocity}}

Thx

1 Like

Funny, it’s working.

My approach that days didn’t work so I came to this aweful work around.

Thanks

I made a little update:

{{velocity}}
  ## omit space XWiki as I don't want user profiles in there
  #set ($xwql = "where doc.hidden = false AND doc.space NOT LIKE 'XWiki'")
  ## array of all pages
  #set ($allItems = $services.query.xwql($xwql).execute())
  ## count the pages
  #set ($count = $allItems.size())
  #foreach($i in [1..100])
    #set ($randomnumber = $mathtool.random(0, $count))
    #set ($randomPage = $allItems[$randomnumber])
    ## redirect to random page if accessible by user
    #if ($xwiki.hasAccessLevel('view', $randomPage))
      #set($randomPage = $xwiki.getURL($randomPage))
      $response.sendRedirect($randomPage)
    #else
      ## do nothing just try another random number in the loop
    #end
  #end
{{/velocity}}

I added a small loop instead of reloading the page if the user can’t access the random page. This avoids unnecessary database accesses.