# Hooks, REST API and WP-CLI - Roleline 1.x documentation

> Filters and actions around capabilities, safety checks and changes; the roleline/v1 REST API; and the wp roleline commands.

## Filters

| Filter | What it's for |
|---|---|
| `roleline_capability_group` | The group a capability is listed in (`$group, $cap`). Return a new key and give it a label with `roleline_capability_group_labels` |
| `roleline_capability_group_labels` | Group labels (key => label) |
| `roleline_capability_descriptions` | Descriptions (capability => text), e.g. for your plugin's capabilities |
| `roleline_required_capabilities` | What nobody can take away from themselves (default `roleline_manage_roles`, `promote_users`, `edit_users`, `list_users`) |
| `roleline_protected_capabilities` | The Administrator role's capabilities whose removal needs a confirmation (WordPress's defaults) |
| `roleline_risky_capabilities` | Capabilities whose granting to a role needs a confirmation |
| `roleline_unrestricted` | Whether a user may grant capabilities they don't have (`$unrestricted, $user_id`; default: super admins on multisite, else `manage_options`) |
| `roleline_assignable_roles` | Roles the current user may give users or take away (slug => name) |
| `roleline_backups_keep` | How many backups are kept (50) |
| `roleline_delete_role_limit` | How many users a role may have to be deleted on Users → Roles or with the REST API (1000); bigger roles are deleted with `wp roleline delete` |
| `roleline_admin_tabs` | Tabs on Users → Roles (key => label); print one with the `roleline_admin_tab_{key}` action |
| `roleline_roles_columns` | Columns of the roles list; print one with `roleline_roles_column` (`$column, $slug`) |

Describing your plugin's capabilities and grouping them:

```php
add_filter( 'roleline_capability_descriptions', function ( $descriptions ) {
	$descriptions['view_reports'] = 'See the sales reports.';
	return $descriptions;
} );

add_filter( 'roleline_capability_group', function ( $group, $cap ) {
	return 0 === strpos( $cap, 'acme_' ) ? 'acme' : $group;
}, 10, 2 );
add_filter( 'roleline_capability_group_labels', function ( $labels ) {
	return $labels + array( 'acme' => 'Acme Reports' );
} );
```

## Actions

| Action | When |
|---|---|
| `roleline_loaded` | Roleline has loaded (on `plugins_loaded`). Add-ons hook their features here |
| `roleline_before_roles_change` | Before a change is saved, after the backup (`$label, $old_roles, $new_roles`) |
| `roleline_roles_changed` | After a change is saved (`$label, $old_roles, $new_roles`) |
| `roleline_role_deleted` | A role was deleted and its users moved (`$slug, $reassign, $user_ids`) |
| `roleline_capability_deleted` | An unused capability was deleted (`$cap`) |
| `roleline_backup_created` / `roleline_backup_restored` | A backup was made (`$id, $label`) / restored (`$id`) |
| `roleline_user_roles_changed` | A user's roles changed through Roleline (`$user_id, $added, $removed`) |
| `roleline_user_role_after` | Prints after a role on a user's profile (`$user, $slug, $has, $allowed`) |
| `roleline_editor_sidebar` | Prints below Save on the role editor (`$role`) |
| `roleline_admin_load` / `roleline_admin_notices` | Users → Roles is loading (`$tab`) / prints its notices |

Logging every change:

```php
add_action( 'roleline_roles_changed', function ( $label, $old, $new ) {
	error_log( 'Roles changed by ' . wp_get_current_user()->user_login . ': ' . $label );
}, 10, 3 );
```

## PHP API

`Extendiment\Roleline\Roles` (`create()`, `update()`, `delete()`, `reset()`, `set_default()`, `commit()`), `Users` (`set_roles()`, `add_role()`, `remove_role()`, `assignable()`), `Backups` (`create()`, `all()`, `restore()`, `compare()`) and `Capabilities` (`all()`, `grouped()`, `add_custom()`, `delete()`) are public. Changes return `true` or a `WP_Error`: `roleline_blocked` (refused; reasons in `errors`) or `roleline_confirm` (send again with `array( 'confirm' => true )`).

## REST API

Namespace `roleline/v1`, for users with `roleline_manage_roles` (a user's roles: for whoever may promote that user). Authenticate as usual (cookie and nonce, or application passwords).

| Route | Methods |
|---|---|
| `/roles` | `GET` list, `POST` create (`name`, `slug`, `copy_from`) |
| `/roles/{role}` | `GET`, `POST`/`PUT`/`PATCH` (`name`, `capabilities` as the full set, or `add` / `remove`), `DELETE` (`reassign`) |
| `/roles/{role}/preview` | `POST`: what a change would do, with `errors` and `warnings`, without saving |
| `/roles/{role}/reset` | `POST` |
| `/default-role` | `POST` (`role`) |
| `/capabilities` | `GET` grouped, `POST` add (`name`) |
| `/capabilities/{cap}` | `DELETE` (unused ones) |
| `/backups` | `GET`, `POST` (`label`) |
| `/backups/{id}` | `GET`: compared with now |
| `/backups/{id}/restore` | `POST` |
| `/export` | `GET` (`roles[]`) |
| `/import` | `POST` (`data`, `roles[]`, `dry_run`) |
| `/users/{id}/roles` | `GET`, `PUT` (`roles[]`) |

A refused change answers `403` with `errors`; a risky one `409` with `warnings` until it's sent again with `"confirm": true`.

```bash
curl -u admin:APP_PASSWORD -X POST https://example.com/wp-json/roleline/v1/roles/support_agent \
  -H 'Content-Type: application/json' -d '{"add":["moderate_comments"]}'
```

## WP-CLI

| Command | What it does |
|---|---|
| `wp roleline list` | Roles with users and capability counts |
| `wp roleline delete <role> [--reassign=<role>] [--yes]` | Deletes a role of any size, without checks; users without another role get `--reassign` |
| `wp roleline backups` | The backups, newest first |
| `wp roleline backup [--label=…]` | Backs up now |
| `wp roleline restore [<id>] [--yes]` | Restores a backup (the latest by default), without checks |
| `wp roleline reset <role>… [--all] [--yes]` | Resets WordPress's roles to their defaults |
| `wp roleline repair [--user=…]` | Puts the Administrator role's capabilities back; optionally makes a user an administrator |
| `wp roleline export [<file>] [--roles=…]` | Exports roles as JSON |
| `wp roleline import <file> [--yes]` | Imports roles from a file |

Source: https://extendiment.com/plugins/roleline/docs/1.x/hooks
