Skip to content

Permissions

QUIQQER packages declare permissions in permissions.xml and check those permissions in PHP or JavaScript before protected actions are executed.

Permissions are package-owned names. Use a stable prefix that matches the package or domain, for example quiqqer.bricks.*.

Declare Permissions

Create permissions.xml in the package root.

xml
<?xml version="1.0" encoding="UTF-8"?>
<permissions>
    <permission name="vendor.package.action" type="bool" area="admin">
        <defaultvalue>0</defaultvalue>
    </permission>
</permissions>

Real package shape:

xml
<?xml version="1.0" encoding="UTF-8"?>
<permissions>
    <permission name="quiqqer.bricks.create" type="bool">
        <defaultvalue>1</defaultvalue>
    </permission>

    <permission name="quiqqer.bricks.delete" type="bool">
        <defaultvalue>1</defaultvalue>
    </permission>
</permissions>

Permission Names

Permission names should be specific enough to describe the protected action.

Good examples:

  • quiqqer.bricks.create
  • quiqqer.bricks.edit
  • quiqqer.bricks.delete
  • quiqqer.bricks.assign

Avoid broad names such as vendor.package.admin when the package has several independent actions. Fine-grained permissions are easier to assign and audit.

Default Values

Use <defaultvalue> to define the initial value after the permission is imported.

xml
<permission name="vendor.package.delete" type="bool">
    <defaultvalue>0</defaultvalue>
</permission>

For security-sensitive actions, default to disabled and let administrators grant the permission explicitly. Destructive actions and actions that expose protected data are typical examples for explicit permissions.

Type, Area, And Group Defaults

Each permission can define a type and an area.

xml
<permission name="vendor.package.publish" type="bool" area="admin">
    <defaultvalue>0</defaultvalue>
    <rootPermission>1</rootPermission>
    <everyonePermission>0</everyonePermission>
    <guestPermission>0</guestPermission>
</permission>

Use type="bool" for normal allow/deny permissions. Use the area to group permissions in administration views.

The optional group defaults set initial values for the root, everyone, and guest groups when no assignment exists yet. Use them sparingly; package permissions should not silently grant broad access unless that is required for normal operation.

QUIQQER derives backend labels from the package and permission name. Add locale entries for the generated title and description keys when administrators should see translated permission texts.

Check Permissions In PHP

Use the permission API before performing protected operations.

php
QUI\Permissions\Permission::checkPermission(
    'vendor.package.action',
    $PermissionUser
);

If no explicit permission user is passed to your method, use the current session user before checking the permission.

php
if ($PermissionUser === null) {
    $PermissionUser = QUI::getUserBySession();
}

QUI\Permissions\Permission::checkPermission(
    'quiqqer.bricks.edit',
    $PermissionUser
);

Some existing package code uses hasPermission() in places where the method is expected to throw on missing permission. For new documentation examples, checkPermission() is the clearer choice when an operation must stop without permission.

Check Permissions In JavaScript

Backend JavaScript can check a permission before enabling a protected UI action.

js
require(['Permissions'], function (Permissions) {
    Permissions.hasPermission('vendor.package.action').then(function (has) {
        if (!has) {
            return;
        }

        // Enable the protected action.
    });
});

Client-side checks are for user experience. Always protect the server-side PHP operation as well.

Method Design

Package methods that perform protected actions should accept an optional permission user.

php
public function post(?QUI\Interfaces\Users\User $PermissionUser = null): void
{
    if ($PermissionUser === null) {
        $PermissionUser = QUI::getUserBySession();
    }

    QUI\Permissions\Permission::checkPermission(
        'vendor.package.post',
        $PermissionUser
    );

    // Perform the protected operation.
}

This keeps the method usable from backend requests, console tools, setup code, and tests while making the permission context explicit.

Practical Checklist

Before adding a permission:

  • Use a package-scoped permission name.
  • Choose the narrowest useful action name.
  • Set type and area deliberately.
  • Set a safe default value.
  • Use group defaults only when the initial assignment is intentional.
  • Check the permission in the PHP operation, not only in the UI.
  • Pass the permission user through service methods when actions can be triggered from different contexts.
  • Add localized labels for backend permission management when the package exposes the permission to administrators.

Released under GPL-3.0-or-later.