Checking user permissions in PHP

After a couple hours reading the docs and forum and trying a lot of things, I finally managed to understand how one can check user permissions in PHP. Let me share my findings here in case it saves a couple hours for the next person. ^^

(Unless I missed it, I think it might be completely missing from the Guide and Cookbook, and can be hard to find in the Reference — you have to look at the generated class reference and find classes named Permissions and figure out what they are and how to get instances.)

Defining user roles and permissions

This part is pretty well documented in the Guide:

Getting the current user in PHP

// returns null or a Kirby\Cms\User object representing the current user
$user = $kirby->user();

Note that because it may return null if the current visitor is anonymous (not signed in as a Kirby user), you should check that $user != null before trying to work with the $user object.

:open_book: This part is documented in the reference: $user | Kirby CMS

Checking a user’s generic permissions

Generic permissions for a user depend on the user’s role. To access them, you have to go through the user’s Kirby\Cms\Role object to access a Kirby\Cms\Permissions object, like this:

$user = $kirby->user();
if ($user != null) {
  $permissions = $user->role()->permissions();
  // can the current user sign in to the Panel?
  var_dump($permissions->for('access', 'panel'));
  // can the current user create pages?
  var_dump($permissions->for('pages', 'create'));
}

:warning: Be careful to not use $user->permissions() instead of $user->role()->permissions(). This is a different permissions object with a different API that represents something completely different. See the next section…

:open_book: I don’t think this part is documented at all (outside of the automatically generated class reference). Closed I could find was this topic about Kirby v2 with an update about Kirby v3: Is It Possible to Check if User Has 'Change URL' Permission? - #16 by texnixe

Checking that the user can manipulate some content model

To check generic permissions from the user’s role, we accessed a Kirby\Cms\Permissions object via $user->role()->permissions(). There are a handful of other permissions objects in Kirby, which all extend the Kirby\Cms\ModelPermissions class:

  • Kirby\Cms\FilePermissions
  • Kirby\Cms\PagePermissions
  • Kirby\Cms\SitePermissions
  • Kirby\Cms\UserPermissions

As far as I understand, these represent the permissions that the current user has to act on those content models. The logic here is something like “I have a Page ($page), can the current user modify it (update)?”

Usage may look like:

$user = kirby()->user();
$page = page('some/page');

if ($user != null) {
  // can the current user update the selected page?
  var_dump($page->permissions()->can('update'));
}

:warning: Note that the API looks like $permissions->can('permissionName'), which is different from the role permissions which can be checked with $permissions->for('categoryName', 'permissionName').

:open_book: As far as I can tell, this API is only documented in the class reference (and doesn’t have examples), which makes it a bit hard to find. Best places to look at seem to be:

2 Likes