# Sub-user Hooks

https://dev.wisecp.com/es/subuser-hooks

The seven hooks over inviting, accepting, updating and removing sub-users.

## Overview

Somebody else reaching an account starts with an invitation and ends with an acceptance. Every step between has its own hook: inviting, resending, accepting, updating, suspending and removing.

Three separate numbers must be kept apart: the **account**, the **person** reaching it and the sub-user **record**. Mixing them grants rights on the wrong account.

## Reference

### Following a sub-user invitation

actionuser.subuser_invited

`AccountUsers` invitation waiting

Runs when a sub-user is invited to an account. **There is no access yet**: the invitation waits until it is accepted.

Parameters 4

$owner_idintThe account owner sending it.

$subuser_idintThe waiting invitation record created.

$emailstringThe invited address. That address **need not** already have an account.

$permsarrayThe permissions to be granted.

Return 1

voidThe return is ignored.

Listener PHP

```php
Hook::add('action:user.subuser_invited', 10, function ($owner_id, $subuser_id, $email, $perms) {
    // There is NO access yet: the invitation is waiting.
    Acme::noteInvite($owner_id, $email);
});
```

### Following an invitation being accepted

actionuser.subuser_accepted

`AccountUsers` access starts here

Runs when a sub-user accepts an invitation. **Access begins at this point**.

Parameters 3

$owner_idintThe account access was granted on.

$user_idintThe **real** user id of the sub-user; this is who signs in.

$subuser_idintThe id of the sub-user record. Three separate numbers: the account, the person and the record. Mixing them grants rights on the wrong account.

Return 1

voidThe return is ignored.

Listener PHP

```php
Hook::add('action:user.subuser_accepted', 10, function ($owner_id, $user_id, $subuser_id) {
    // Three separate numbers: the account, the person, the record.
    Acme::grantAccess($owner_id, $user_id);
});
```

### Following a sub-user being added

actionuser.subuser_added

`AccountUsers` added by an admin

Runs when a sub-user is added to an account.

Parameters 2

$user_idintThe account owner.

$subuserarrayThe record created: address, label and permissions.

Return 1

voidThe return is ignored.

Listener PHP

```php
Hook::add('action:user.subuser_added', 10, function ($user_id, $subuser) {
    Acme::syncTeam($user_id, $subuser);
});
```

### Following a sub-user update

actionuser.subuser_updated

`AccountUsers` permissions included

Runs when the details or permissions of a sub-user change.

Parameters 2

$owner_idintThe account owner.

$subuserarrayThe updated data: address, label, status and permissions.

Return 1

voidThe return is ignored.

Listener PHP

```php
Hook::add('action:user.subuser_updated', 10, function ($owner_id, $subuser) {
    Acme::syncPermissions($owner_id, $subuser);
});
```

### Following a sub-user status change

actionuser.subuser_status_changed

`AccountUsers` suspension

Runs when a sub-user is suspended or brought back.

Parameters 3

$owner_idintThe account owner.

$subuser_idintThe id of the record that changed.

$statusstringThe new state: `active` or `inactive`.

Return 1

voidThe return is ignored.

Listener PHP

```php
Hook::add('action:user.subuser_status_changed', 10,
    function ($owner_id, $subuser_id, $status) {
        if ($status === 'inactive') Acme::revokeTokens($subuser_id);
    });
```

### Following an invitation being sent again

actionuser.subuser_invite_resent

`AccountUsers` sent again

Runs when a waiting invitation is sent again.

Parameters 2

$owner_idintThe account owner sending it.

$subuser_idintThe record of the invitation resent.

Return 1

voidThe return is ignored.

Listener PHP

```php
Hook::add('action:user.subuser_invite_resent', 10, function ($owner_id, $subuser_id) {
    Acme::noteResend($owner_id, $subuser_id);
});
```

### Following a sub-user being removed

actionuser.subuser_deleted

`AccountUsers` after deletion

Runs after a sub-user is removed from an account.

Parameters 2

$owner_idintThe account owner.

$subuserarrayThe full record before deletion: address, status and permissions.

Return 1

voidThe return is ignored.

Listener PHP

```php
Hook::add('action:user.subuser_deleted', 10, function ($owner_id, $subuser) {
    Acme::revokeAllAccess($owner_id, $subuser['email'] ?? '');
});
```

## Pitfalls

> **There are three separate numbers**
> 
> The acceptance hook carries three ids: the **account** access was granted on, the **person** signing in and the sub-user **record**. Using the wrong one writes rights against another account.

> **An invitation is not access**
> 
> When the invitation hook runs the other party can **reach nothing yet**. Access begins at the acceptance hook. A listener that opens rights on invitation turns an unaccepted invitation into real access.

## Related Articles

- [Customer Account Hooks](https://dev.wisecp.com/en/customer-account-hooks)
- [Invoice Lifecycle Hooks](https://dev.wisecp.com/en/invoice-lifecycle-hooks)
- [How Hooks Work](https://dev.wisecp.com/en/how-hooks-work)
